diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-05-27 20:43:48 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2015-05-30 17:36:31 +0200 |
commit | 09312c200b78c6b441b577911743f75921fef5b3 (patch) | |
tree | 170b0a46b29b0e5efea500b9544d9b513b6f7668 /src/TII.cpp | |
parent | 405de3ecd5624a350668406f5476905e5e8a1286 (diff) | |
download | dabmod-09312c200b78c6b441b577911743f75921fef5b3.tar.gz dabmod-09312c200b78c6b441b577911743f75921fef5b3.tar.bz2 dabmod-09312c200b78c6b441b577911743f75921fef5b3.zip |
Add and enable TII insertion for testing
Diffstat (limited to 'src/TII.cpp')
-rw-r--r-- | src/TII.cpp | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/TII.cpp b/src/TII.cpp new file mode 100644 index 0000000..9ccc6e0 --- /dev/null +++ b/src/TII.cpp @@ -0,0 +1,297 @@ +/* + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty + the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2015 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org + */ +/* + This file is part of ODR-DabMod. + + ODR-DabMod 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. + + ODR-DabMod 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 ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "TII.h" +#include "PcDebug.h" + +#include <stdio.h> +#include <stdexcept> +#include <string.h> + +typedef std::complex<float> complexf; + +/* TII pattern for TM I, II, IV */ +const int pattern_tm1_2_4[][8] = { // {{{ + {0,0,0,0,1,1,1,1}, + {0,0,0,1,0,1,1,1}, + {0,0,0,1,1,0,1,1}, + {0,0,0,1,1,1,0,1}, + {0,0,0,1,1,1,1,0}, + {0,0,1,0,0,1,1,1}, + {0,0,1,0,1,0,1,1}, + {0,0,1,0,1,1,0,1}, + {0,0,1,0,1,1,1,0}, + {0,0,1,1,0,0,1,1}, + {0,0,1,1,0,1,0,1}, + {0,0,1,1,0,1,1,0}, + {0,0,1,1,1,0,0,1}, + {0,0,1,1,1,0,1,0}, + {0,0,1,1,1,1,0,0}, + {0,1,0,0,0,1,1,1}, + {0,1,0,0,1,0,1,1}, + {0,1,0,0,1,1,0,1}, + {0,1,0,0,1,1,1,0}, + {0,1,0,1,0,0,1,1}, + {0,1,0,1,0,1,0,1}, + {0,1,0,1,0,1,1,0}, + {0,1,0,1,1,0,0,1}, + {0,1,0,1,1,0,1,0}, + {0,1,0,1,1,1,0,0}, + {0,1,1,0,0,0,1,1}, + {0,1,1,0,0,1,0,1}, + {0,1,1,0,0,1,1,0}, + {0,1,1,0,1,0,0,1}, + {0,1,1,0,1,0,1,0}, + {0,1,1,0,1,1,0,0}, + {0,1,1,1,0,0,0,1}, + {0,1,1,1,0,0,1,0}, + {0,1,1,1,0,1,0,0}, + {0,1,1,1,1,0,0,0}, + {1,0,0,0,0,1,1,1}, + {1,0,0,0,1,0,1,1}, + {1,0,0,0,1,1,0,1}, + {1,0,0,0,1,1,1,0}, + {1,0,0,1,0,0,1,1}, + {1,0,0,1,0,1,0,1}, + {1,0,0,1,0,1,1,0}, + {1,0,0,1,1,0,0,1}, + {1,0,0,1,1,0,1,0}, + {1,0,0,1,1,1,0,0}, + {1,0,1,0,0,0,1,1}, + {1,0,1,0,0,1,0,1}, + {1,0,1,0,0,1,1,0}, + {1,0,1,0,1,0,0,1}, + {1,0,1,0,1,0,1,0}, + {1,0,1,0,1,1,0,0}, + {1,0,1,1,0,0,0,1}, + {1,0,1,1,0,0,1,0}, + {1,0,1,1,0,1,0,0}, + {1,0,1,1,1,0,0,0}, + {1,1,0,0,0,0,1,1}, + {1,1,0,0,0,1,0,1}, + {1,1,0,0,0,1,1,0}, + {1,1,0,0,1,0,0,1}, + {1,1,0,0,1,0,1,0}, + {1,1,0,0,1,1,0,0}, + {1,1,0,1,0,0,0,1}, + {1,1,0,1,0,0,1,0}, + {1,1,0,1,0,1,0,0}, + {1,1,0,1,1,0,0,0}, + {1,1,1,0,0,0,0,1}, + {1,1,1,0,0,0,1,0}, + {1,1,1,0,0,1,0,0}, + {1,1,1,0,1,0,0,0}, + {1,1,1,1,0,0,0,0} }; // }}} + + +TII::TII(unsigned int dabmode, unsigned int comb, unsigned int pattern) : + ModCodec(ModFormat(0), ModFormat(0)), + m_dabmode(dabmode), + m_comb(comb), + m_pattern(pattern), + m_insert(true) +{ + PDEBUG("TII::TII(%u) @ %p\n", dabmode, this); + + std::stringstream ss; + ss << "TII(comb:" << m_comb << ", pattern:" << m_pattern << ")"; + m_name = ss.str(); + + switch (m_dabmode) { + case 1: + m_carriers = 1536; + + if (not(0 <= m_pattern and m_pattern <= 69) ) { + throw std::runtime_error( + "TII::TII pattern not valid!"); + } + break; + case 2: + m_carriers = 384; + + if (not(0 <= m_pattern and m_pattern <= 69) ) { + throw std::runtime_error( + "TII::TII pattern not valid!"); + } + break; + /* unsupported + case 3: + m_carriers = 192; + break; + case 4: + d_dabmode = 0; + case 0: + */ + default: + std::stringstream ss_exception; + ss_exception << + "TII::TII DAB mode " << m_dabmode << " not valid!"; + throw std::runtime_error(ss_exception.str()); + } + + if (not(0 < m_comb and m_comb <= 23) ) { + throw std::runtime_error( + "TII::TII comb not valid!"); + } + + m_dataIn.clear(); + m_dataIn.resize(m_carriers); + prepare_pattern(); + + myOutputFormat.size(m_carriers * sizeof(complexf)); +} + + +TII::~TII() +{ + PDEBUG("TII::~TII() @ %p\n", this); +} + + +int TII::process(Buffer* const dataIn, Buffer* dataOut) +{ + PDEBUG("TII::process(dataIn: %p, dataOut: %p)\n", + dataIn, dataOut); + + if ((dataIn != NULL) && (dataIn->getLength() != 0)) { + throw std::runtime_error( + "TII::process input size not valid!"); + } + + if (m_insert) { + dataOut->setData(&m_dataIn[0], m_carriers * sizeof(complexf)); + } + else { + dataOut->setLength(m_carriers * sizeof(complexf)); + bzero(dataOut->getData(), dataOut->getLength()); + } + + // TODO wrong! Must align with frames containing the right data + m_insert = not m_insert; + + return 1; +} + +void TII::enable_carrier(int k) { + fprintf(stderr, "k = %d\n", k); + + int ix = m_carriers/2 + k; + + if (ix < 0 or ix > (ssize_t)m_dataIn.size()) { + throw std::runtime_error( + "TII::enable_carrier invalid k!"); + } + + m_dataIn[ix] = 1.0; // TODO power of the carrier ? +} + +void TII::prepare_pattern() { + int comb = m_comb; // Convert from unsigned to signed + + // This could be written more efficiently, but since it is + // not performance-critial, it makes sense to write it + // in the same way as the specification in + // ETSI EN 300 401 Clause 14.8 + if (m_dabmode == 1) { + for (int k = -768; k < -384; k++) { + for (int b = 0; b < 8; b++) { + if ( k == -768 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + } + + for (int k = -384; k < -0; k++) { + for (int b = 0; b < 8; b++) { + if ( k == -384 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + } + + for (int k = 1; k <= 384; k++) { + for (int b = 0; b < 8; b++) { + if ( k == 1 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + } + + for (int k = 384; k <= 768; k++) { + for (int b = 0; b < 8; b++) { + if ( k == 385 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + } + } + else if (m_dabmode == 2) { + for (int k = -192; k <= 192; k++) { + for (int b = 0; b < 4; b++) { + if ( k == -192 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + + for (int b = 4; b < 8; b++) { + if ( k == -191 + 2 * comb + 48 * b and + pattern_tm1_2_4[m_pattern][b]) { + enable_carrier(k); + enable_carrier(k+1); + } + } + } + } + else { + throw std::runtime_error( + "TII::TII DAB mode not valid!"); + } + + +} + +#ifdef TII_TEST +int main(int argc, char** argv) +{ + const unsigned int mode = 2; + const unsigned int comb = 4; + const unsigned int pattern = 16; + TII tii(mode, comb, pattern); + + return 0; +} +#endif + |