summaryrefslogtreecommitdiffstats
path: root/src/PhaseReference.cpp
diff options
context:
space:
mode:
authorMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
committerMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
commite92f9c408634810828e75d4ad6da408e1c142195 (patch)
treed4e622617f58a70ed3dd2e57418f73f412e7193b /src/PhaseReference.cpp
downloaddabmod-e92f9c408634810828e75d4ad6da408e1c142195.tar.gz
dabmod-e92f9c408634810828e75d4ad6da408e1c142195.tar.bz2
dabmod-e92f9c408634810828e75d4ad6da408e1c142195.zip
added unmodified mmbtools
Diffstat (limited to 'src/PhaseReference.cpp')
-rw-r--r--src/PhaseReference.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/PhaseReference.cpp b/src/PhaseReference.cpp
new file mode 100644
index 0000000..bebbec6
--- /dev/null
+++ b/src/PhaseReference.cpp
@@ -0,0 +1,168 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty
+ the Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ CRC-DADMOD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PhaseReference.h"
+#include "PcDebug.h"
+
+#include <stdio.h>
+#include <stdexcept>
+#include <complex>
+#include <string.h>
+
+typedef std::complex<float> complexf;
+
+
+const unsigned char PhaseReference::d_h[4][32] = {
+ { 0, 2, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1,
+ 0, 2, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1 },
+ { 0, 3, 2, 3, 0, 1, 3, 0, 2, 1, 2, 3, 2, 3, 3, 0,
+ 0, 3, 2, 3, 0, 1, 3, 0, 2, 1, 2, 3, 2, 3, 3, 0 },
+ { 0, 0, 0, 2, 0, 2, 1, 3, 2, 2, 0, 2, 2, 0, 1, 3,
+ 0, 0, 0, 2, 0, 2, 1, 3, 2, 2, 0, 2, 2, 0, 1, 3 },
+ { 0, 1, 2, 1, 0, 3, 3, 2, 2, 3, 2, 1, 2, 1, 3, 2,
+ 0, 1, 2, 1, 0, 3, 3, 2, 2, 3, 2, 1, 2, 1, 3, 2 }
+};
+
+
+PhaseReference::PhaseReference(size_t dabmode) :
+ ModCodec(ModFormat(0), ModFormat(0)),
+ d_dabmode(dabmode)
+{
+ PDEBUG("PhaseReference::PhaseReference(%zu) @ %p\n", dabmode, this);
+
+ switch (d_dabmode) {
+ case 1:
+ d_carriers = 1536;
+ d_num = 2048;
+ break;
+ case 2:
+ d_carriers = 384;
+ d_num = 512;
+ break;
+ case 3:
+ d_carriers = 192;
+ d_num = 256;
+ break;
+ case 4:
+ d_dabmode = 0;
+ case 0:
+ d_carriers = 768;
+ d_num = 1024;
+ break;
+ default:
+ throw std::runtime_error(
+ "PhaseReference::PhaseReference DAB mode not valid!");
+ }
+ d_dataIn = new complexf[d_num];
+ fillData();
+
+ myOutputFormat.size(d_carriers * sizeof(complexf));
+}
+
+
+PhaseReference::~PhaseReference()
+{
+ PDEBUG("PhaseReference::~PhaseReference() @ %p\n", this);
+
+ delete[] d_dataIn;
+}
+
+
+complexf convert(unsigned char data) {
+ const complexf value[] = {
+ complexf(1, 0),
+ complexf(0, 1),
+ complexf(-1, 0),
+ complexf(0, -1),
+ };
+ return value[data % 4];
+}
+
+
+void PhaseReference::fillData()
+{
+ size_t index;
+ size_t offset;
+ size_t k;
+
+ const int table[][48][2] = {
+ { // Mode 0/4
+ // Positive part
+ { 0, 0 }, { 3, 1 }, { 2, 0 }, { 1, 2 }, { 0, 0 }, { 3, 1 },
+ { 2, 2 }, { 1, 2 }, { 0, 2 }, { 3, 1 }, { 2, 3 }, { 1, 0 },
+ // Negative part
+ { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 0, 2 }, { 1, 2 },
+ { 2, 0 }, { 3, 3 }, { 0, 3 }, { 1, 1 }, { 2, 3 }, { 3, 2 },
+ },
+ { // Mode 1
+ // Positive part
+ { 0, 3 }, { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 2 }, { 3, 2 },
+ { 2, 1 }, { 1, 0 }, { 0, 2 }, { 3, 2 }, { 2, 3 }, { 1, 3 },
+ { 0, 0 }, { 3, 2 }, { 2, 1 }, { 1, 3 }, { 0, 3 }, { 3, 3 },
+ { 2, 3 }, { 1, 0 }, { 0, 3 }, { 3, 0 }, { 2, 1 }, { 1, 1 },
+ // Negative part
+ { 0, 1 }, { 1, 2 }, { 2, 0 }, { 3, 1 }, { 0, 3 }, { 1, 2 },
+ { 2, 2 }, { 3, 3 }, { 0, 2 }, { 1, 1 }, { 2, 2 }, { 3, 3 },
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 3 }, { 0, 2 }, { 1, 2 },
+ { 2, 2 }, { 3, 1 }, { 0, 1 }, { 1, 3 }, { 2, 1 }, { 3, 2 },
+ },
+ { // Mode 2
+ // Positive part
+ { 2, 0 }, { 1, 2 }, { 0, 2 }, { 3, 1 }, { 2, 0 }, { 1, 3 },
+ // Negative part
+ { 0, 2 }, { 1, 3 }, { 2, 2 }, { 3, 2 }, { 0, 1 }, { 1, 2 },
+ },
+ { // Mode 3
+ // Positive part
+ { 3, 2 }, { 2, 2 }, { 1, 2 },
+ // Negative part
+ { 0, 2 }, { 1, 3 }, { 2, 0 },
+ },
+ };
+
+ if ((d_dabmode < 0) || (d_dabmode > 3)) {
+ throw std::runtime_error(
+ "PhaseReference::fillData invalid DAB mode!");
+ }
+
+ for (index = 0, offset = 0; index < d_carriers; ++offset) {
+ for (k = 0; k < 32; ++k) {
+ d_dataIn[index++] = convert(d_h[table[d_dabmode][offset][0]][k]
+ + table[d_dabmode][offset][1]);
+ }
+ }
+}
+
+
+int PhaseReference::process(Buffer* const dataIn, Buffer* dataOut)
+{
+ PDEBUG("PhaseReference::process(dataIn: %p, dataOut: %p)\n",
+ dataIn, dataOut);
+
+ if ((dataIn != NULL) && (dataIn->getLength() != 0)) {
+ throw std::runtime_error(
+ "PhaseReference::process input size not valid!");
+ }
+
+ dataOut->setData(d_dataIn, d_carriers * sizeof(complexf));
+
+ return 1;
+}