/*
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 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 .
*/
#include "SubchannelSource.h"
#include "PcDebug.h"
#include
#include
#include
#include
#define P1 0xc8888888
#define P2 0xc888c888
#define P3 0xc8c8c888
#define P4 0xc8c8c8c8
#define P5 0xccc8c8c8
#define P6 0xccc8ccc8
#define P7 0xccccccc8
#define P8 0xcccccccc
#define P9 0xeccccccc
#define P10 0xeccceccc
#define P11 0xecececcc
#define P12 0xecececec
#define P13 0xeeececec
#define P14 0xeeeceeec
#define P15 0xeeeeeeec
#define P16 0xeeeeeeee
#define P17 0xfeeeeeee
#define P18 0xfeeefeee
#define P19 0xfefefeee
#define P20 0xfefefefe
#define P21 0xfffefefe
#define P22 0xfffefffe
#define P23 0xfffffffe
#define P24 0xffffffff
const std::vector& SubchannelSource::get_rules()
{
return d_puncturing_rules;
}
SubchannelSource::SubchannelSource(eti_STC &stc) :
ModInput(ModFormat(0), ModFormat(stc.getSTL() * 8)),
d_start_address(stc.getStartAddress()),
d_framesize(stc.getSTL() * 8),
d_protection(stc.TPL)
{
PDEBUG("SubchannelSource::SubchannelSource(...) @ %p\n", this);
// PDEBUG(" Start address: %i\n", d_start_address);
// PDEBUG(" Framesize: %i\n", d_framesize);
// PDEBUG(" Protection: %i\n", d_protection);
if (protectionForm()) {
if (protectionOption() == 0) {
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(
((6 * bitrate() / 8) - 3) * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P23));
break;
case 2:
if (bitrate() == 8) {
d_puncturing_rules.push_back(new PuncturingRule(
5 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(
1 * 16, P12));
} else {
d_puncturing_rules.push_back(new PuncturingRule(
((2 * bitrate() / 8) - 3) * 16, P14));
d_puncturing_rules.push_back(new PuncturingRule(
((4 * bitrate() / 8) + 3) * 16, P13));
}
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(
((6 * bitrate() / 8) - 3) * 16, P8));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P7));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(
((4 * bitrate() / 8) - 3) * 16, P3));
d_puncturing_rules.push_back(new PuncturingRule(
((2 * bitrate() / 8) + 3) * 16, P2));
break;
default:
fprintf(stderr,
"Protection form(%zu), option(%zu) and level(%zu)\n",
protectionForm(), protectionOption(), protectionLevel());
fprintf(stderr, "Subchannel TPL: 0x%x (%u)\n", stc.TPL, stc.TPL);
throw std::runtime_error("SubchannelSource::SubchannelSource "
"unknown protection level!");
}
} else if (protectionOption() == 1) {
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(
((24 * bitrate() / 32) - 3) * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P9));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(
((24 * bitrate() / 32) - 3) * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P5));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(
((24 * bitrate() / 32) - 3) * 16, P4));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P3));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(
((24 * bitrate() / 32) - 3) * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(
3 * 16, P1));
break;
default:
fprintf(stderr,
"Protection form(%zu), option(%zu) and level(%zu)\n",
protectionForm(), protectionOption(), protectionLevel());
fprintf(stderr, "Subchannel TPL: 0x%x (%u)\n", stc.TPL, stc.TPL);
throw std::runtime_error("SubchannelSource::SubchannelSource "
"unknown protection level!");
}
} else {
fprintf(stderr,
"Protection form(%zu), option(%zu) and level(%zu)\n",
protectionForm(), protectionOption(), protectionLevel());
fprintf(stderr, "Subchannel TPL: 0x%x (%u)\n", stc.TPL, stc.TPL);
throw std::runtime_error("SubchannelSource::SubchannelSource "
"unknown protection option!");
}
} else {
bool error = false;
switch (bitrate()) {
case 32:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(5 * 16, P17));
d_puncturing_rules.push_back(new PuncturingRule(13 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P17));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P22));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(14 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P15));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(14 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P8 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(18 * 16, P5 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P3 ));
d_puncturing_rules.push_back(new PuncturingRule(17 * 16, P2 ));
break;
default:
error = true;
}
break;
case 48:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(5 * 16, P18));
d_puncturing_rules.push_back(new PuncturingRule(25 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P18));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P14));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P15));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P15));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(4 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P3 ));
break;
default:
error = true;
}
break;
case 56:
switch (protectionLevel()) {
case 2:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P23));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(23 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P7 ));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(23 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P5 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(23 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P3 ));
break;
default:
error = true;
}
break;
case 64:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P18));
d_puncturing_rules.push_back(new PuncturingRule(28 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P18));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P23));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(29 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(27 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(9 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(33 * 16, P5 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(9 * 16, P3 ));
d_puncturing_rules.push_back(new PuncturingRule(31 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(2 * 16, P3 ));
break;
default:
error = true;
}
break;
case 80:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P17));
d_puncturing_rules.push_back(new PuncturingRule(41 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P18));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P23));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(41 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(40 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P7 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(41 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P3 ));
d_puncturing_rules.push_back(new PuncturingRule(41 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P3 ));
break;
default:
error = true;
}
break;
case 96:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(13 * 16, P18));
d_puncturing_rules.push_back(new PuncturingRule(50 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P19));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P22));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(53 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P12));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(6 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(51 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(7 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(10 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(52 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(7 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(9 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(53 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P4 ));
break;
default:
error = true;
}
break;
case 112:
switch (protectionLevel()) {
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P23));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(49 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P14));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(23 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(47 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(49 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P8 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(14 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(17 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(50 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P5 ));
break;
default:
error = true;
}
break;
case 128:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(20 * 16, P17));
d_puncturing_rules.push_back(new PuncturingRule(62 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P19));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P22));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(61 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P14));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(60 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(61 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P7 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(19 * 16, P3 ));
d_puncturing_rules.push_back(new PuncturingRule(62 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P4 ));
break;
default:
error = true;
}
break;
case 160:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P18));
d_puncturing_rules.push_back(new PuncturingRule(84 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P19));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P22));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(85 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P8 ));
d_puncturing_rules.push_back(new PuncturingRule(82 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P11));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P11));
d_puncturing_rules.push_back(new PuncturingRule(23 * 16, P6 ));
d_puncturing_rules.push_back(new PuncturingRule(83 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9 ));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P5 ));
d_puncturing_rules.push_back(new PuncturingRule(19 * 16, P4 ));
d_puncturing_rules.push_back(new PuncturingRule(87 * 16, P2 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P4 ));
break;
default:
error = true;
}
break;
case 192:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(21 * 16, P20));
d_puncturing_rules.push_back(new PuncturingRule(109 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P24));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P22));
d_puncturing_rules.push_back(new PuncturingRule(20 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(110 * 16, P9));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(106 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P11));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(108 * 16, P4));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(20 * 16, P4));
d_puncturing_rules.push_back(new PuncturingRule(110 * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P5));
break;
default:
error = true;
}
break;
case 224:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P20));
d_puncturing_rules.push_back(new PuncturingRule(130 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P20));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(132 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P15));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(20 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(134 * 16, P7));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P9));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P8));
d_puncturing_rules.push_back(new PuncturingRule(127 * 16, P4));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P11));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P8));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(131 * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6));
break;
default:
error = true;
}
break;
case 256:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P19));
d_puncturing_rules.push_back(new PuncturingRule(152 * 16, P14));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P18));
break;
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(22 * 16, P14));
d_puncturing_rules.push_back(new PuncturingRule(156 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P13));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(27 * 16, P10));
d_puncturing_rules.push_back(new PuncturingRule(151 * 16, P7));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P12));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P9));
d_puncturing_rules.push_back(new PuncturingRule(154 * 16, P5));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P5));
d_puncturing_rules.push_back(new PuncturingRule(154 * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P5));
break;
default:
error = true;
}
break;
case 320:
switch (protectionLevel()) {
case 2:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P17));
d_puncturing_rules.push_back(new PuncturingRule(200 * 16, P9 ));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P17));
break;
case 4:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P13));
d_puncturing_rules.push_back(new PuncturingRule(25 * 16, P9));
d_puncturing_rules.push_back(new PuncturingRule(201 * 16, P5));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P8));
d_puncturing_rules.push_back(new PuncturingRule(26 * 16, P5));
d_puncturing_rules.push_back(new PuncturingRule(200 * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P6));
break;
default:
error = true;
}
break;
case 384:
switch (protectionLevel()) {
case 1:
d_puncturing_rules.push_back(new PuncturingRule(12 * 16, P24));
d_puncturing_rules.push_back(new PuncturingRule(28 * 16, P20));
d_puncturing_rules.push_back(new PuncturingRule(245 * 16, P14));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P23));
break;
case 3:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P16));
d_puncturing_rules.push_back(new PuncturingRule(24 * 16, P9));
d_puncturing_rules.push_back(new PuncturingRule(250 * 16, P7));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P10));
break;
case 5:
d_puncturing_rules.push_back(new PuncturingRule(11 * 16, P8));
d_puncturing_rules.push_back(new PuncturingRule(27 * 16, P6));
d_puncturing_rules.push_back(new PuncturingRule(247 * 16, P2));
d_puncturing_rules.push_back(new PuncturingRule(3 * 16, P7));
break;
default:
error = true;
}
break;
default:
error = true;
}
if (error) {
fprintf(stderr, " Protection: UEP-%zu @ %zukb/s\n",
protectionLevel(), bitrate());
throw std::runtime_error("SubchannelSource::SubchannelSource "
"UEP puncturing rules does not exist!");
}
}
}
SubchannelSource::~SubchannelSource()
{
PDEBUG("SubchannelSource::~SubchannelSource() @ %p\n", this);
for (unsigned i = 0; i < d_puncturing_rules.size(); ++i) {
// PDEBUG(" Deleting rules @ %p\n", d_puncturing_rules[i]);
delete d_puncturing_rules[i];
}
}
size_t SubchannelSource::startAddress()
{
return d_start_address;
}
size_t SubchannelSource::framesize()
{
return d_framesize;
}
size_t SubchannelSource::framesizeCu()
{
size_t framesizeCu = 0;
if (protectionForm()) { // Long form
if ((d_protection >> 2) & 0x07) { // Option
switch (d_protection & 0x03) {
case 0:
framesizeCu = (bitrate() / 32) * 27;
break;
case 1:
framesizeCu = (bitrate() / 32) * 21;
break;
case 2:
framesizeCu = (bitrate() / 32) * 18;
break;
case 3:
framesizeCu = (bitrate() / 32) * 15;
break;
default:
framesizeCu = 0xffff;
break;
}
} else {
switch (d_protection & 0x03) {
case 0:
framesizeCu = (bitrate() / 8) * 12;
break;
case 1:
framesizeCu = (bitrate() / 8) * 8;
break;
case 2:
framesizeCu = (bitrate() / 8) * 6;
break;
case 3:
framesizeCu = (bitrate() / 8) * 4;
break;
default:
framesizeCu = 0xffff;
break;
}
}
} else { // Short form
switch (bitrate()) {
case 32:
switch (protectionLevel()) {
case 1:
framesizeCu = 35;
break;
case 2:
framesizeCu = 29;
break;
case 3:
framesizeCu = 24;
break;
case 4:
framesizeCu = 21;
break;
case 5:
framesizeCu = 16;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 48:
switch (protectionLevel()) {
case 1:
framesizeCu = 52;
break;
case 2:
framesizeCu = 42;
break;
case 3:
framesizeCu = 35;
break;
case 4:
framesizeCu = 29;
break;
case 5:
framesizeCu = 24;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 56:
switch (protectionLevel()) {
case 2:
framesizeCu = 52;
break;
case 3:
framesizeCu = 42;
break;
case 4:
framesizeCu = 35;
break;
case 5:
framesizeCu = 29;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 64:
switch (protectionLevel()) {
case 1:
framesizeCu = 70;
break;
case 2:
framesizeCu = 58;
break;
case 3:
framesizeCu = 48;
break;
case 4:
framesizeCu = 42;
break;
case 5:
framesizeCu = 32;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 80:
switch (protectionLevel()) {
case 1:
framesizeCu = 84;
break;
case 2:
framesizeCu = 70;
break;
case 3:
framesizeCu = 58;
break;
case 4:
framesizeCu = 52;
break;
case 5:
framesizeCu = 40;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 96:
switch (protectionLevel()) {
case 1:
framesizeCu = 104;
break;
case 2:
framesizeCu = 84;
break;
case 3:
framesizeCu = 70;
break;
case 4:
framesizeCu = 58;
break;
case 5:
framesizeCu = 48;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 112:
switch (protectionLevel()) {
case 2:
framesizeCu = 104;
break;
case 3:
framesizeCu = 84;
break;
case 4:
framesizeCu = 70;
break;
case 5:
framesizeCu = 58;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 128:
switch (protectionLevel()) {
case 1:
framesizeCu = 140;
break;
case 2:
framesizeCu = 116;
break;
case 3:
framesizeCu = 96;
break;
case 4:
framesizeCu = 84;
break;
case 5:
framesizeCu = 64;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 160:
switch (protectionLevel()) {
case 1:
framesizeCu = 168;
break;
case 2:
framesizeCu = 140;
break;
case 3:
framesizeCu = 116;
break;
case 4:
framesizeCu = 104;
break;
case 5:
framesizeCu = 80;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 192:
switch (protectionLevel()) {
case 1:
framesizeCu = 208;
break;
case 2:
framesizeCu = 168;
break;
case 3:
framesizeCu = 140;
break;
case 4:
framesizeCu = 116;
break;
case 5:
framesizeCu = 96;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 224:
switch (protectionLevel()) {
case 1:
framesizeCu = 232;
break;
case 2:
framesizeCu = 208;
break;
case 3:
framesizeCu = 168;
break;
case 4:
framesizeCu = 140;
break;
case 5:
framesizeCu = 116;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 256:
switch (protectionLevel()) {
case 1:
framesizeCu = 280;
break;
case 2:
framesizeCu = 232;
break;
case 3:
framesizeCu = 192;
break;
case 4:
framesizeCu = 168;
break;
case 5:
framesizeCu = 128;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 320:
switch (protectionLevel()) {
case 2:
framesizeCu = 280;
break;
case 4:
framesizeCu = 208;
break;
case 5:
framesizeCu = 160;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
case 384:
switch (protectionLevel()) {
case 1:
framesizeCu = 416;
break;
case 3:
framesizeCu = 280;
break;
case 5:
framesizeCu = 192;
break;
default:
framesizeCu = 0xffff;
break;
}
break;
default:
framesizeCu = 0xffff;
break;
}
}
if (framesizeCu == 0) {
fprintf(stderr, " Protection %zu @ %zu kb/s\n",
protectionLevel(), bitrate());
throw std::runtime_error("SubchannelSource::framesizeCu protection "
"not yet coded!");
}
if (framesizeCu == 0xffff) {
fprintf(stderr, " Protection %zu @ %zu kb/s\n",
protectionLevel(), bitrate());
throw std::runtime_error("SubchannelSource::framesizeCu invalid "
"protection!");
}
return framesizeCu;
}
size_t SubchannelSource::bitrate()
{
return d_framesize / 3;
}
size_t SubchannelSource::protection()
{
return d_protection;
}
size_t SubchannelSource::protectionForm()
{
return (d_protection >> 5) & 1;
}
size_t SubchannelSource::protectionLevel()
{
if (protectionForm()) { // Long form
return (d_protection & 0x3) + 1;
} // Short form
return (d_protection & 0x7) + 1;
}
size_t SubchannelSource::protectionOption()
{
if (protectionForm()) { // Long form
return (d_protection >> 2) & 0x7;
} // Short form
return 0;
}
int SubchannelSource::process(Buffer* inputData, Buffer* outputData)
{
PDEBUG("SubchannelSource::process"
"(inputData: %p, outputData: %p)\n",
inputData, outputData);
if (inputData != NULL && inputData->getLength()) {
PDEBUG(" Input, storing data\n");
if (inputData->getLength() != d_framesize) {
PDEBUG("ERROR: Subchannel::process.inputSize != d_framesize\n");
exit(-1);
}
d_buffer = *inputData;
return inputData->getLength();
}
PDEBUG(" Output, retriving data\n");
return read(outputData);
}
int SubchannelSource::read(Buffer* outputData)
{
PDEBUG("SubchannelSource::read(outputData: %p, outputSize: %zu)\n",
outputData, outputData->getLength());
if (d_buffer.getLength() != d_framesize) {
PDEBUG("ERROR: Subchannel::read.outputSize != d_framesize\n");
exit(-1);
}
*outputData = d_buffer;
return outputData->getLength();
}