diff options
author | Matthias (think) <matthias@mpb.li> | 2012-07-11 11:49:12 +0200 |
---|---|---|
committer | Matthias (think) <matthias@mpb.li> | 2012-07-11 11:49:12 +0200 |
commit | e92f9c408634810828e75d4ad6da408e1c142195 (patch) | |
tree | d4e622617f58a70ed3dd2e57418f73f412e7193b /src/FrequencyInterleaver.cpp | |
download | dabmod-e92f9c408634810828e75d4ad6da408e1c142195.tar.gz dabmod-e92f9c408634810828e75d4ad6da408e1c142195.tar.bz2 dabmod-e92f9c408634810828e75d4ad6da408e1c142195.zip |
added unmodified mmbtools
Diffstat (limited to 'src/FrequencyInterleaver.cpp')
-rw-r--r-- | src/FrequencyInterleaver.cpp | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp new file mode 100644 index 0000000..7930682 --- /dev/null +++ b/src/FrequencyInterleaver.cpp @@ -0,0 +1,131 @@ +/* + 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 "FrequencyInterleaver.h" +#include "PcDebug.h" + +#include <stdio.h> +#include <stdexcept> +#include <malloc.h> +#include <complex> + +typedef std::complex<float> complexf; + + +FrequencyInterleaver::FrequencyInterleaver(size_t mode) : + ModCodec(ModFormat(0), ModFormat(0)) +{ + PDEBUG("FrequencyInterleaver::FrequencyInterleaver(%zu) @ %p\n", + mode, this); + + size_t num; + size_t alpha = 13; + size_t beta; + switch (mode) { + case 1: + d_carriers = 1536; + num = 2048; + beta = 511; + break; + case 2: + d_carriers = 384; + num = 512; + beta = 127; + break; + case 3: + d_carriers = 192; + num = 256; + beta = 63; + break; + case 0: + case 4: + d_carriers = 768; + num = 1024; + beta = 255; + break; + default: + PDEBUG("Carriers: %zu\n", (d_carriers >> 1) << 1); + throw std::runtime_error("FrequencyInterleaver::FrequencyInterleaver " + "nb of carriers invalid!"); + break; + } + + d_indexes = (size_t*)memalign(16, d_carriers * sizeof(size_t)); + size_t* index = d_indexes; + size_t perm = 0; + PDEBUG("i: %4u, R: %4u\n", 0, 0); + for (size_t j = 1; j < num; ++j) { + perm = (alpha * perm + beta) & (num - 1); + if (perm >= ((num - d_carriers) / 2) + && perm <= (num - (num - d_carriers) / 2) + && perm != (num / 2)) { + PDEBUG("i: %4zu, R: %4zu, d: %4zu, n: %4zu, k: %5zi, index: %zu\n", + j, perm, perm, index - d_indexes, perm - num / 2, + perm > num / 2 + ? perm - (1 + (num / 2)) + : perm + (d_carriers - (num / 2))); + *(index++) = perm > num / 2 ? + perm - (1 + (num / 2)) : perm + (d_carriers - (num / 2)); + } else { + PDEBUG("i: %4zu, R: %4zu\n", j, perm); + } + } +} + + +FrequencyInterleaver::~FrequencyInterleaver() +{ + PDEBUG("FrequencyInterleaver::~FrequencyInterleaver() @ %p\n", this); + + free(d_indexes); +} + + +int FrequencyInterleaver::process(Buffer* const dataIn, Buffer* dataOut) +{ + PDEBUG("FrequencyInterleaver::process" + "(dataIn: %p, sizeIn: %zu, dataOut: %p, sizeOut: %zu)\n", + dataIn, dataIn->getLength(), dataOut, dataOut->getLength()); + + dataOut->setLength(dataIn->getLength()); + + 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_carriers != 0) { + throw std::runtime_error( + "FrequencyInterleaver::process input size not valid!"); + } + + for (size_t i = 0; i < sizeIn;) { +// memset(out, 0, d_carriers * sizeof(complexf)); + for (size_t j = 0; j < d_carriers; i += 4, j += 4) { + out[d_indexes[j]] = in[i]; + out[d_indexes[j + 1]] = in[i + 1]; + out[d_indexes[j + 2]] = in[i + 2]; + out[d_indexes[j + 3]] = in[i + 3]; + } + out += d_carriers; + } + + return 1; +} |