aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Buffer.cpp88
-rw-r--r--src/Buffer.h44
-rw-r--r--src/ConfigParser.cpp6
-rw-r--r--src/ConfigParser.h3
-rw-r--r--src/ConvEncoder.cpp1
-rw-r--r--src/DabMod.cpp31
-rw-r--r--src/DabModulator.cpp7
-rw-r--r--src/EtiReader.cpp11
-rw-r--r--src/EtiReader.h1
-rw-r--r--src/FIRFilter.cpp5
-rw-r--r--src/FicSource.cpp1
-rw-r--r--src/Flowgraph.cpp7
-rw-r--r--src/FormatConverter.cpp1
-rw-r--r--src/FrameMultiplexer.cpp5
-rw-r--r--src/FrameMultiplexer.h10
-rw-r--r--src/FrequencyInterleaver.cpp9
-rw-r--r--src/GainControl.cpp12
-rw-r--r--src/GainControl.h2
-rw-r--r--src/GuardIntervalInserter.cpp263
-rw-r--r--src/GuardIntervalInserter.h64
-rw-r--r--src/MemlessPoly.cpp5
-rw-r--r--src/NullSymbol.cpp2
-rw-r--r--src/OfdmGenerator.cpp14
-rw-r--r--src/PrbsGenerator.cpp7
-rw-r--r--src/PrbsGenerator.h2
-rw-r--r--src/PuncturingEncoder.cpp1
-rw-r--r--src/RemoteControl.cpp18
-rw-r--r--src/Resampler.cpp10
-rw-r--r--src/Socket.h1
-rw-r--r--src/SubchannelSource.cpp1
-rw-r--r--src/TII.cpp23
-rw-r--r--src/TII.h3
-rw-r--r--src/TimeInterleaver.cpp1
-rw-r--r--src/TimestampDecoder.cpp6
-rw-r--r--src/Utils.cpp6
-rw-r--r--src/Utils.h1
-rw-r--r--src/porting.c13
-rw-r--r--src/porting.h20
38 files changed, 471 insertions, 234 deletions
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 8631c42..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
@@ -28,48 +28,72 @@
#include "Buffer.h"
#include "PcDebug.h"
+#include <string>
#include <stdlib.h>
#include <string.h>
-#include <malloc.h>
-#if HAVE_DECL__MM_MALLOC
-# include <mm_malloc.h>
-#else
-# define memalign(a, b) malloc(b)
-#endif
-
-
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_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<uint8_t> &vec)
{
PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size());
- this->len = 0;
- this->size = 0;
- this->data = NULL;
+ m_len = 0;
+ m_capacity = 0;
+ m_data = nullptr;
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);
+ if (m_data) {
+ free(m_data);
+ }
}
Buffer &Buffer::operator=(const Buffer &copy)
{
- setData(copy.data, copy.len);
+ setData(copy.m_data, copy.m_len);
+ 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;
}
@@ -81,26 +105,30 @@ Buffer &Buffer::operator=(const std::vector<uint8_t> &copy)
Buffer &Buffer::operator+=(const Buffer &copy)
{
- 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_capacity) {
+ void *tmp = m_data;
/* Align to 32-byte boundary for AVX. */
- data = memalign(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));
+ }
- if (tmp != NULL) {
- memcpy(data, tmp, this->len);
+ if (tmp != nullptr) {
+ memcpy(m_data, tmp, m_len);
free(tmp);
}
- size = len;
+ m_capacity = len;
}
- this->len = len;
+ m_len = len;
}
@@ -113,10 +141,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);
- if (data != NULL) {
- memcpy((char*)this->data + offset, data, len);
+ size_t offset = m_len;
+ setLength(m_len + len);
+ if (data != nullptr) {
+ memcpy((char*)m_data + offset, data, len);
}
}
diff --git a/src/Buffer.h b/src/Buffer.h
index 8c5c768..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 len;
-
- /* Allocated size of the Buffer */
- size_t size;
-
- /* Pointer to the data. Memory allocation is entirely
- * handled by setLength.
- */
- void *data;
-
public:
using sptr = std::shared_ptr<Buffer>;
- Buffer(const Buffer& copy) = default;
- Buffer(const std::vector<uint8_t> &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<uint8_t>& 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 &copy);
- Buffer &operator=(const std::vector<uint8_t> &copy);
+ Buffer& operator=(const Buffer& copy);
+ Buffer& operator=(Buffer&& other);
+ Buffer& operator=(const std::vector<uint8_t>& 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 &copy);
+ Buffer& operator+=(const Buffer& copy);
+
+ size_t getLength() const { return m_len; }
+ 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;
- size_t getLength() const { return len; }
- void *getData() const { return data; }
};
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 8facec3..0e641c0 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -161,8 +161,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 dd6c040..3f64883 100644
--- a/src/ConfigParser.h
+++ b/src/ConfigParser.h
@@ -79,6 +79,9 @@ 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) || defined(HAVE_SOAPYSDR)
Output::SDRDeviceConfig sdr_device_config;
#endif
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 <stdlib.h>
#include <stdio.h>
#include <stdexcept>
+#include <string>
const static uint8_t PARITY[] = {
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index d29b489..4961910 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"
#include "output/SDR.h"
#include "output/UHD.h"
#include "output/Soapy.h"
@@ -61,13 +62,6 @@
# include <netinet/in.h>
#endif
-#if HAVE_DECL__MM_MALLOC
-# include <mm_malloc.h>
-#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
@@ -203,6 +197,10 @@ static shared_ptr<ModOutput> prepare_output(
output = make_shared<OutputFile>(s.outputName);
}
+ else {
+ throw runtime_error("File output format " + s.fileOutputFormat +
+ " not known");
+ }
}
#if defined(HAVE_OUTPUT_UHD)
else if (s.useUHDOutput) {
@@ -451,7 +449,7 @@ int launch_modulator(int argc, char* argv[])
}
}
#if defined(HAVE_ZEROMQ)
- else if (auto in = dynamic_pointer_cast<InputZeroMQReader>(inputReader)) {
+ else if (dynamic_pointer_cast<InputZeroMQReader>(inputReader)) {
run_again = true;
// Create a new input reader
auto inputZeroMQReader = make_shared<InputZeroMQReader>();
@@ -459,7 +457,8 @@ int launch_modulator(int argc, char* argv[])
inputReader = inputZeroMQReader;
}
#endif
- else if (auto in = dynamic_pointer_cast<InputTcpReader>(inputReader)) {
+ else if (dynamic_pointer_cast<InputTcpReader>(inputReader)) {
+ // Create a new input reader
auto inputTcpReader = make_shared<InputTcpReader>();
inputTcpReader->Open(mod_settings.inputName);
inputReader = inputTcpReader;
@@ -535,17 +534,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/DabModulator.cpp b/src/DabModulator.cpp
index 2bd33b4..1ea06de 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);
@@ -205,7 +204,9 @@ int DabModulator::process(Buffer* dataOut)
rcs.enrol(cifGain.get());
auto cifGuard = make_shared<GuardIntervalInserter>(
- myNbSymbols, mySpacing, myNullSize, mySymSize);
+ myNbSymbols, mySpacing, myNullSize, mySymSize,
+ m_settings.ofdmWindowOverlap);
+ rcs.enrol(cifGuard.get());
shared_ptr<FIRFilter> cifFilter;
if (not m_settings.filterTapsFilename.empty()) {
diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp
index 0b27126..d84ed1f 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);
@@ -208,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;
@@ -218,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;
@@ -231,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;
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<std::shared_ptr<SubchannelSource> > mySources;
diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp
index 4296822..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);
@@ -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 <stdexcept>
+#include <string>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp
index 6ee7b81..465ef41 100644
--- a/src/Flowgraph.cpp
+++ b/src/Flowgraph.cpp
@@ -26,15 +26,10 @@
#include "Flowgraph.h"
#include "PcDebug.h"
+#include <string>
#include <memory>
#include <algorithm>
#include <sstream>
-
-#if HAVE_DECL__MM_MALLOC
-# include <mm_malloc.h>
-#else
-# define memalign(a, b) malloc(b)
-#endif
#include <sys/types.h>
#include <stdexcept>
#include <assert.h>
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 <malloc.h>
#include <sys/types.h>
#include <string.h>
#include <stdexcept>
diff --git a/src/FrameMultiplexer.cpp b/src/FrameMultiplexer.cpp
index 1cfaadd..5dc6dca 100644
--- a/src/FrameMultiplexer.cpp
+++ b/src/FrameMultiplexer.cpp
@@ -28,6 +28,7 @@
#include "PcDebug.h"
#include <stdio.h>
+#include <string>
#include <stdexcept>
#include <complex>
#include <memory>
@@ -73,7 +74,7 @@ int FrameMultiplexer::process(std::vector<Buffer*> 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()));
@@ -81,7 +82,7 @@ int FrameMultiplexer::process(std::vector<Buffer*> 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 <sys/types.h>
+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<Buffer*> dataIn, Buffer* dataOut);
const char* name() { return "FrameMultiplexer"; }
diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp
index 29d54bb..e76d525 100644
--- a/src/FrequencyInterleaver.cpp
+++ b/src/FrequencyInterleaver.cpp
@@ -24,7 +24,8 @@
#include <stdio.h>
#include <stdexcept>
-#include <malloc.h>
+#include <string>
+#include <stdlib.h>
#include <complex>
typedef std::complex<float> complexf;
@@ -68,7 +69,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/GainControl.cpp b/src/GainControl.cpp
index 2a91b12..0411482 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/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp
index 80ba900..14027d3 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.
@@ -21,57 +26,101 @@
#include "GuardIntervalInserter.h"
#include "PcDebug.h"
-
-
-#include <sys/types.h>
#include <string.h>
#include <stdexcept>
#include <complex>
+#include <mutex>
typedef std::complex<float> 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) {
- myHasNull = true;
- } else {
- myHasNull = false;
+ 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);
-GuardIntervalInserter::~GuardIntervalInserter()
+ 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)
{
- PDEBUG("GuardIntervalInserter::~GuardIntervalInserter() @ %p\n", this);
+ std::lock_guard<std::mutex> 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<std::mutex> 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<const complexf*>(dataIn->getData());
complexf* out = reinterpret_cast<complexf*>(dataOut->getData());
size_t sizeIn = dataIn->getLength() / sizeof(complexf);
- if (sizeIn != (d_nbSymbols + (myHasNull ? 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);
@@ -81,24 +130,176 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut)
"GuardIntervalInserter::process input size not valid!");
}
- // Null symbol
- if (myHasNull) {
+ // 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++) {
+ /* _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 = 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 bool last_symbol = (sym_ix + 1 >= d_nbSymbols);
+ if (last_symbol) {
+ // No windowing at all at end
+ 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[ox],
+ &in[ix],
+ (d_spacing - d_windowOverlap) * sizeof(complexf));
+ 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; ox < (ssize_t)d_symSize; i++) {
+ out[ox] = in[ix] * d_window[2*d_windowOverlap - (i+1)];
+ ox++;
+ ix++;
+ }
+ assert(ix == d_spacing);
+
+ ix = 0;
+ // Cyclic suffix, with window from 0.5 to 0
+ 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);
+ }
+
+ 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.
+ }
+ }
+ 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 - (nullSize - spacing) = 2 * spacing - nullSize
- 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 70a8fcd..7714c1a 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.
@@ -25,29 +30,48 @@
# include <config.h>
#endif
-
#include "ModPlugin.h"
+#include "RemoteControl.h"
+#include <stdint.h>
+#include <vector>
-#include <sys/types.h>
+/* The GuardIntervalInserter prepends the cyclic prefix to all
+ * 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,
+ size_t windowOverlap = 0);
+ int process(Buffer* const dataIn, Buffer* dataOut);
+ const char* name() { return "GuardIntervalInserter"; }
-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&);
-
-
- 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;
- bool myHasNull;
+ /******* 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<float> d_window;
};
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 <stdio.h>
#include <stdexcept>
-
+#include <string>
#include <future>
#include <array>
#include <iostream>
@@ -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/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..915d568 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],
@@ -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/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 <stdexcept>
+#include <string>
#include <stdio.h>
#include <stdlib.h>
-#include <stdexcept>
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/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;
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 <string>
#include <stdio.h>
#include <stdexcept>
#include <stdint.h>
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 &param_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 8069a61..42951c5 100644
--- a/src/Resampler.cpp
+++ b/src/Resampler.cpp
@@ -27,10 +27,11 @@
#include "Resampler.h"
#include "PcDebug.h"
-#include <malloc.h>
+#include <string>
+#include <stdexcept>
+#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
-#include <stdexcept>
#include <assert.h>
#define FFT_REAL(x) x[0]
@@ -81,7 +82,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]);
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 <unistd.h>
#include <cstdint>
#include <stdexcept>
+#include <string>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <errno.h>
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 <string>
#include <stdexcept>
#include <sys/types.h>
#include <stdlib.h>
diff --git a/src/TII.cpp b/src/TII.cpp
index 4710ed4..446d9c6 100644
--- a/src/TII.cpp
+++ b/src/TII.cpp
@@ -190,17 +190,13 @@ 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);
complexf* in = reinterpret_cast<complexf*>(dataIn->getData());
complexf* out = reinterpret_cast<complexf*>(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]) {
@@ -350,10 +339,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/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<bool> m_enabled_carriers;
};
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 <vector>
+#include <string>
#include <stdint.h>
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());
}
}
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 385253b..f113be3 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -27,7 +27,9 @@
#include "Utils.h"
#include "GainControl.h"
-#include <sys/prctl.h>
+#if defined(HAVE_PRCTL)
+# include <sys/prctl.h>
+#endif
#include <pthread.h>
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 2bc6cb3..5d5831b 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
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 <sys/timeb.h>
-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 <http://www.gnu.org/licenses/>.
*/
-#ifndef PORTING_H
-#define PORTING_H
+#pragma once
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-#ifndef HAVE_BZERO
-# define bzero(s, n) memset(s, 0, n)
-#endif
-
-#ifndef HAVE_GETTIMEOFDAY
-#include <sys/time.h>
-#ifdef __cplusplus
-extern "C"
-#endif
-int gettimeofday(struct timeval* t, void* timezone);
-#endif
-
#ifdef _WIN32
#include <fcntl.h>
// 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