aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-02-12 17:51:48 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-02-12 17:51:48 +0100
commit6eb9a403558d4dfde1de36e5c6744b58dc26ea79 (patch)
tree60f35619167d007ab7ef3a3af3573d3a9c8e8501
parente659399f872832552a5fdae02e70f4579f0e266e (diff)
downloaddabmod-6eb9a403558d4dfde1de36e5c6744b58dc26ea79.tar.gz
dabmod-6eb9a403558d4dfde1de36e5c6744b58dc26ea79.tar.bz2
dabmod-6eb9a403558d4dfde1de36e5c6744b58dc26ea79.zip
Fix incorrect frame size bug due to missing puncturing padding
-rw-r--r--src/ConvEncoder.cpp7
-rw-r--r--src/DabModulator.cpp2
-rw-r--r--src/PuncturingEncoder.cpp33
-rw-r--r--src/PuncturingEncoder.h17
-rw-r--r--src/SubchannelSource.cpp47
-rw-r--r--src/SubchannelSource.h4
6 files changed, 82 insertions, 28 deletions
diff --git a/src/ConvEncoder.cpp b/src/ConvEncoder.cpp
index 74de34f..06b2e85 100644
--- a/src/ConvEncoder.cpp
+++ b/src/ConvEncoder.cpp
@@ -111,6 +111,7 @@ int ConvEncoder::process(Buffer* const dataIn, Buffer* dataOut)
}
++in_offset;
}
+
for (unsigned pad_count = 0; pad_count < 3; ++pad_count) {
out[out_offset] = 0;
// For each 4-bit output word
@@ -138,5 +139,11 @@ int ConvEncoder::process(Buffer* const dataIn, Buffer* dataOut)
PDEBUG(" Consume: %zu\n", in_offset);
PDEBUG(" Return: %zu\n", out_offset);
+
+ if (out_offset != dataOut->getLength()) {
+ throw std::runtime_error("Assertion error: ConvEncoder output " +
+ std::to_string(out_offset) + " == " +
+ std::to_string(dataOut->getLength()) + " fail");
+ }
return out_offset;
}
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp
index cbe8f07..827b73f 100644
--- a/src/DabModulator.cpp
+++ b/src/DabModulator.cpp
@@ -302,7 +302,7 @@ int DabModulator::process(Buffer* dataOut)
auto subchConv = make_shared<ConvEncoder>(subchSizeIn);
// Configuring puncturing encoder
- auto subchPunc = make_shared<PuncturingEncoder>();
+ auto subchPunc = make_shared<PuncturingEncoder>(subchannel->framesizeCu());
for (const auto& rule : subchannel->get_rules()) {
PDEBUG(" Adding rule:\n");
diff --git a/src/PuncturingEncoder.cpp b/src/PuncturingEncoder.cpp
index a212a93..9bd9004 100644
--- a/src/PuncturingEncoder.cpp
+++ b/src/PuncturingEncoder.cpp
@@ -35,12 +35,23 @@
PuncturingEncoder::PuncturingEncoder() :
ModCodec(),
+ d_num_cu(0),
d_in_block_size(0),
d_out_block_size(0),
d_tail_rule()
{
PDEBUG("PuncturingEncoder() @ %p\n", this);
+}
+PuncturingEncoder::PuncturingEncoder(
+ size_t num_cu) :
+ ModCodec(),
+ d_num_cu(num_cu),
+ d_in_block_size(0),
+ d_out_block_size(0),
+ d_tail_rule()
+{
+ PDEBUG("PuncturingEncoder(%zu) @ %p\n", num_cu, this);
}
void PuncturingEncoder::adjust_item_size()
@@ -104,12 +115,29 @@ int PuncturingEncoder::process(Buffer* const dataIn, Buffer* dataOut)
PDEBUG(" in block size: %zu\n", d_in_block_size);
PDEBUG(" out block size: %zu\n", d_out_block_size);
+ if (d_num_cu > 0) {
+ if (d_num_cu * 8 == d_out_block_size + 1) {
+ /* EN 300 401 Table 31 in 11.3.1 UEP coding specifies
+ * that we need one byte of padding
+ */
+ d_out_block_size = d_num_cu * 8;
+ }
+
+ if (d_num_cu * 8 != d_out_block_size) {
+ throw std::runtime_error(
+ "PuncturingEncoder encoder initialisation failed. "
+ " CU: " + std::to_string(d_num_cu) +
+ " block_size: " + std::to_string(d_out_block_size));
+ }
+ }
+
dataOut->setLength(d_out_block_size);
const unsigned char* in = reinterpret_cast<const unsigned char*>(dataIn->getData());
unsigned char* out = reinterpret_cast<unsigned char*>(dataOut->getData());
if (dataIn->getLength() != d_in_block_size) {
- throw std::runtime_error("PuncturingEncoder::process wrong input size");
+ throw std::runtime_error(
+ "PuncturingEncoder::process wrong input size");
}
if (d_tail_rule) {
@@ -167,7 +195,8 @@ int PuncturingEncoder::process(Buffer* const dataIn, Buffer* dataOut)
++out_count;
}
}
- for (size_t i = d_out_block_size; i < dataOut->getLength(); ++i) {
+
+ for (size_t i = out_count; i < dataOut->getLength(); ++i) {
out[out_count++] = 0;
}
diff --git a/src/PuncturingEncoder.h b/src/PuncturingEncoder.h
index 19be53e..b6f9f0e 100644
--- a/src/PuncturingEncoder.h
+++ b/src/PuncturingEncoder.h
@@ -35,13 +35,26 @@
#include "ModPlugin.h"
#include <vector>
+#include <string>
#include <sys/types.h>
#include <boost/optional.hpp>
class PuncturingEncoder : public ModCodec
{
public:
- PuncturingEncoder();
+ /* Initialise a puncturer that does not check if the
+ * outgoing data requires padding. To be used for the
+ * FIC. The size of the output buffer is derived from
+ * the puncturing rules only
+ */
+ PuncturingEncoder(void);
+
+ /* Initialise a puncturer that checks if there is up to
+ * one byte padding needed in the output buffer. See
+ * EN 300 401 Table 31 in 11.3.1 UEP coding. Up to one
+ * byte of padding is added
+ */
+ PuncturingEncoder(size_t num_cu);
void append_rule(const PuncturingRule& rule);
void append_tail_rule(const PuncturingRule& rule);
@@ -51,12 +64,12 @@ public:
size_t getOutputSize() { return d_out_block_size; }
private:
+ size_t d_num_cu;
size_t d_in_block_size;
size_t d_out_block_size;
std::vector<PuncturingRule> d_rules;
boost::optional<PuncturingRule> d_tail_rule;
void adjust_item_size();
-
};
diff --git a/src/SubchannelSource.cpp b/src/SubchannelSource.cpp
index 82636f9..a6b3bc4 100644
--- a/src/SubchannelSource.cpp
+++ b/src/SubchannelSource.cpp
@@ -2,7 +2,7 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 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
@@ -26,6 +26,7 @@
#include "SubchannelSource.h"
#include "PcDebug.h"
+#include "Log.h"
#include <stdexcept>
#include <sys/types.h>
@@ -159,8 +160,9 @@ SubchannelSource::SubchannelSource(
throw std::runtime_error("SubchannelSource::SubchannelSource "
"unknown protection option!");
}
- } else {
- bool error = false;
+ }
+ else {
+ bool rule_error = false;
switch (bitrate()) {
case 32:
switch (protectionLevel()) {
@@ -193,7 +195,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(17 * 16, P2 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 48:
@@ -229,7 +231,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P3 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 56:
@@ -259,7 +261,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P3 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 64:
@@ -294,7 +296,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(2 * 16, P3 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 80:
@@ -330,7 +332,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P3 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 96:
@@ -366,7 +368,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P4 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 112:
@@ -396,7 +398,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P5 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 128:
@@ -432,7 +434,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P4 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 160:
@@ -468,7 +470,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P4 );
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 192:
@@ -504,7 +506,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P5);
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 224:
@@ -540,7 +542,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P6);
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 256:
@@ -576,7 +578,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P5);
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 320:
@@ -600,7 +602,7 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P6);
break;
default:
- error = true;
+ rule_error = true;
}
break;
case 384:
@@ -624,17 +626,18 @@ SubchannelSource::SubchannelSource(
d_puncturing_rules.emplace_back(3 * 16, P7);
break;
default:
- error = true;
+ rule_error = true;
}
break;
default:
- error = true;
+ rule_error = true;
}
- if (error) {
- fprintf(stderr, " Protection: UEP-%zu @ %zukb/s\n",
+
+ if (rule_error) {
+ etiLog.log(error, " Protection: UEP-%zu @ %zukb/s\n",
protectionLevel(), bitrate());
- throw std::runtime_error("SubchannelSource::SubchannelSource "
- "UEP puncturing rules does not exist!");
+ throw std::runtime_error("ubchannelSource "
+ "UEP puncturing rules do not exist!");
}
}
}
diff --git a/src/SubchannelSource.h b/src/SubchannelSource.h
index 2dab941..367bb5a 100644
--- a/src/SubchannelSource.h
+++ b/src/SubchannelSource.h
@@ -2,7 +2,7 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 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
@@ -52,6 +52,8 @@ public:
size_t framesizeCu() const;
size_t bitrate() const;
size_t protection() const;
+
+ /* Return 1 if long form is used, 0 otherwise */
size_t protectionForm() const;
size_t protectionLevel() const;
size_t protectionOption() const;