/* 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(); }