1 /* -*- c++ -*- */
2 /*
3 * Copyright 2015,2016 Free Software Foundation, Inc.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "dvbt_bit_inner_deinterleaver_impl.h"
26 #include <gnuradio/io_signature.h>
27
28 #define MAX_MODULATION_ORDER 6
29 #define INTERLEAVER_BLOCK_SIZE 126
30
31 namespace gr {
32 namespace dtv {
33
34 const int dvbt_bit_inner_deinterleaver_impl::d_bsize = INTERLEAVER_BLOCK_SIZE;
35
36 dvbt_bit_inner_deinterleaver::sptr
make(int nsize,dvb_constellation_t constellation,dvbt_hierarchy_t hierarchy,dvbt_transmission_mode_t transmission)37 dvbt_bit_inner_deinterleaver::make(int nsize,
38 dvb_constellation_t constellation,
39 dvbt_hierarchy_t hierarchy,
40 dvbt_transmission_mode_t transmission)
41 {
42 return gnuradio::get_initial_sptr(new dvbt_bit_inner_deinterleaver_impl(
43 nsize, constellation, hierarchy, transmission));
44 }
45
46 /*
47 * The private constructor
48 */
dvbt_bit_inner_deinterleaver_impl(int nsize,dvb_constellation_t constellation,dvbt_hierarchy_t hierarchy,dvbt_transmission_mode_t transmission)49 dvbt_bit_inner_deinterleaver_impl::dvbt_bit_inner_deinterleaver_impl(
50 int nsize,
51 dvb_constellation_t constellation,
52 dvbt_hierarchy_t hierarchy,
53 dvbt_transmission_mode_t transmission)
54 : block("dvbt_bit_inner_deinterleaver",
55 io_signature::make(1, 1, sizeof(unsigned char) * nsize),
56 io_signature::make(1, 2, sizeof(unsigned char) * nsize)),
57 config(constellation,
58 hierarchy,
59 gr::dtv::C1_2,
60 gr::dtv::C1_2,
61 gr::dtv::GI_1_32,
62 transmission),
63 d_nsize(nsize),
64 d_hierarchy(hierarchy)
65 {
66 d_v = config.d_m;
67 d_hierarchy = config.d_hierarchy;
68
69 d_perm = (unsigned char*)new (std::nothrow) unsigned char[d_v * d_bsize];
70 if (d_perm == NULL) {
71 GR_LOG_FATAL(d_logger,
72 "Bit Inner Deinterleaver, cannot allocate memory for d_perm.");
73 throw std::bad_alloc();
74 }
75
76 // Init permutation table (used for b[e][do])
77 for (int i = 0; i < d_bsize * d_v; i++) {
78 if (d_hierarchy == NH) {
79 d_perm[i] = ((i % d_v) / (d_v / 2)) + 2 * (i % (d_v / 2));
80 } else {
81 d_perm[i] = (i % (d_v - 2)) / ((d_v - 2) / 2) + 2 * (i % ((d_v - 2) / 2)) + 2;
82 }
83 }
84
85 if (d_nsize % d_bsize) {
86 GR_LOG_ERROR(
87 d_logger,
88 boost::format(
89 "Input size must be multiple of block size: nsize: %1% bsize: %2%") %
90 d_nsize % d_bsize);
91 }
92 }
93
94 /*
95 * Our virtual destructor.
96 */
~dvbt_bit_inner_deinterleaver_impl()97 dvbt_bit_inner_deinterleaver_impl::~dvbt_bit_inner_deinterleaver_impl()
98 {
99 delete[] d_perm;
100 }
101
forecast(int noutput_items,gr_vector_int & ninput_items_required)102 void dvbt_bit_inner_deinterleaver_impl::forecast(int noutput_items,
103 gr_vector_int& ninput_items_required)
104 {
105 ninput_items_required[0] = noutput_items;
106 }
107
general_work(int noutput_items,gr_vector_int & ninput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)108 int dvbt_bit_inner_deinterleaver_impl::general_work(
109 int noutput_items,
110 gr_vector_int& ninput_items,
111 gr_vector_const_void_star& input_items,
112 gr_vector_void_star& output_items)
113 {
114 const unsigned char* in = (const unsigned char*)input_items[0];
115 unsigned char* outh = (unsigned char*)output_items[0];
116 unsigned char* outl = (unsigned char*)output_items[1];
117
118 int bmax = noutput_items * d_nsize / d_bsize;
119
120 // First index of d_b is Bit interleaver number
121 // Second index of d_b is the position inside Bit interleaver
122 unsigned char d_b[MAX_MODULATION_ORDER][INTERLEAVER_BLOCK_SIZE];
123
124 for (int bcount = 0; bcount < bmax; bcount++) {
125 for (int w = 0; w < d_bsize; w++) {
126 int c = in[(bcount * d_bsize) + w];
127
128 for (int e = 0; e < d_v; e++) {
129 d_b[e][d_lookup_H[w][e]] = (c >> (d_v - e - 1)) & 1;
130 }
131 }
132
133 for (int i = 0; i < d_bsize; i++) {
134 if (d_hierarchy == NH) {
135 // Create output from demultiplexer
136 int c = 0;
137
138 for (int k = 0; k < d_v; k++) {
139 c = (c << 1) | d_b[d_perm[(d_v * i) + k]][i];
140 }
141
142 outh[(bcount * d_bsize) + i] = c;
143 } else {
144 int c = 0;
145
146 // High priority output - first 2 streams
147 for (int k = 0; k < 2; k++) {
148 c = (c << 1) | d_b[(d_v * i + k) % 2][(d_v * i + k) / 2];
149 }
150
151 outh[(bcount * d_bsize) + i] = c;
152
153 c = 0;
154 // Low priority output - (v - 2) streams
155 for (int k = 2; k < (d_v - 2); k++) {
156 c = (c << 1) | d_b[d_perm[d_v * i + k]][(d_v * i + k) / (d_v - 2)];
157 }
158
159 outl[(bcount * d_bsize) + i] = c;
160 }
161 }
162 }
163
164 // Tell runtime system how many input items we consumed on
165 // each input stream.
166 consume_each(noutput_items);
167
168 // Tell runtime system how many output items we produced.
169 return noutput_items;
170 }
171
172 const int dvbt_bit_inner_deinterleaver_impl::d_lookup_H
173 [INTERLEAVER_BLOCK_SIZE][MAX_MODULATION_ORDER] = {
174 { 0, 63, 105, 42, 21, 84 }, { 1, 64, 106, 43, 22, 85 },
175 { 2, 65, 107, 44, 23, 86 }, { 3, 66, 108, 45, 24, 87 },
176 { 4, 67, 109, 46, 25, 88 }, { 5, 68, 110, 47, 26, 89 },
177 { 6, 69, 111, 48, 27, 90 }, { 7, 70, 112, 49, 28, 91 },
178 { 8, 71, 113, 50, 29, 92 }, { 9, 72, 114, 51, 30, 93 },
179 { 10, 73, 115, 52, 31, 94 }, { 11, 74, 116, 53, 32, 95 },
180 { 12, 75, 117, 54, 33, 96 }, { 13, 76, 118, 55, 34, 97 },
181 { 14, 77, 119, 56, 35, 98 }, { 15, 78, 120, 57, 36, 99 },
182 { 16, 79, 121, 58, 37, 100 }, { 17, 80, 122, 59, 38, 101 },
183 { 18, 81, 123, 60, 39, 102 }, { 19, 82, 124, 61, 40, 103 },
184 { 20, 83, 125, 62, 41, 104 }, { 21, 84, 0, 63, 42, 105 },
185 { 22, 85, 1, 64, 43, 106 }, { 23, 86, 2, 65, 44, 107 },
186 { 24, 87, 3, 66, 45, 108 }, { 25, 88, 4, 67, 46, 109 },
187 { 26, 89, 5, 68, 47, 110 }, { 27, 90, 6, 69, 48, 111 },
188 { 28, 91, 7, 70, 49, 112 }, { 29, 92, 8, 71, 50, 113 },
189 { 30, 93, 9, 72, 51, 114 }, { 31, 94, 10, 73, 52, 115 },
190 { 32, 95, 11, 74, 53, 116 }, { 33, 96, 12, 75, 54, 117 },
191 { 34, 97, 13, 76, 55, 118 }, { 35, 98, 14, 77, 56, 119 },
192 { 36, 99, 15, 78, 57, 120 }, { 37, 100, 16, 79, 58, 121 },
193 { 38, 101, 17, 80, 59, 122 }, { 39, 102, 18, 81, 60, 123 },
194 { 40, 103, 19, 82, 61, 124 }, { 41, 104, 20, 83, 62, 125 },
195 { 42, 105, 21, 84, 63, 0 }, { 43, 106, 22, 85, 64, 1 },
196 { 44, 107, 23, 86, 65, 2 }, { 45, 108, 24, 87, 66, 3 },
197 { 46, 109, 25, 88, 67, 4 }, { 47, 110, 26, 89, 68, 5 },
198 { 48, 111, 27, 90, 69, 6 }, { 49, 112, 28, 91, 70, 7 },
199 { 50, 113, 29, 92, 71, 8 }, { 51, 114, 30, 93, 72, 9 },
200 { 52, 115, 31, 94, 73, 10 }, { 53, 116, 32, 95, 74, 11 },
201 { 54, 117, 33, 96, 75, 12 }, { 55, 118, 34, 97, 76, 13 },
202 { 56, 119, 35, 98, 77, 14 }, { 57, 120, 36, 99, 78, 15 },
203 { 58, 121, 37, 100, 79, 16 }, { 59, 122, 38, 101, 80, 17 },
204 { 60, 123, 39, 102, 81, 18 }, { 61, 124, 40, 103, 82, 19 },
205 { 62, 125, 41, 104, 83, 20 }, { 63, 0, 42, 105, 84, 21 },
206 { 64, 1, 43, 106, 85, 22 }, { 65, 2, 44, 107, 86, 23 },
207 { 66, 3, 45, 108, 87, 24 }, { 67, 4, 46, 109, 88, 25 },
208 { 68, 5, 47, 110, 89, 26 }, { 69, 6, 48, 111, 90, 27 },
209 { 70, 7, 49, 112, 91, 28 }, { 71, 8, 50, 113, 92, 29 },
210 { 72, 9, 51, 114, 93, 30 }, { 73, 10, 52, 115, 94, 31 },
211 { 74, 11, 53, 116, 95, 32 }, { 75, 12, 54, 117, 96, 33 },
212 { 76, 13, 55, 118, 97, 34 }, { 77, 14, 56, 119, 98, 35 },
213 { 78, 15, 57, 120, 99, 36 }, { 79, 16, 58, 121, 100, 37 },
214 { 80, 17, 59, 122, 101, 38 }, { 81, 18, 60, 123, 102, 39 },
215 { 82, 19, 61, 124, 103, 40 }, { 83, 20, 62, 125, 104, 41 },
216 { 84, 21, 63, 0, 105, 42 }, { 85, 22, 64, 1, 106, 43 },
217 { 86, 23, 65, 2, 107, 44 }, { 87, 24, 66, 3, 108, 45 },
218 { 88, 25, 67, 4, 109, 46 }, { 89, 26, 68, 5, 110, 47 },
219 { 90, 27, 69, 6, 111, 48 }, { 91, 28, 70, 7, 112, 49 },
220 { 92, 29, 71, 8, 113, 50 }, { 93, 30, 72, 9, 114, 51 },
221 { 94, 31, 73, 10, 115, 52 }, { 95, 32, 74, 11, 116, 53 },
222 { 96, 33, 75, 12, 117, 54 }, { 97, 34, 76, 13, 118, 55 },
223 { 98, 35, 77, 14, 119, 56 }, { 99, 36, 78, 15, 120, 57 },
224 { 100, 37, 79, 16, 121, 58 }, { 101, 38, 80, 17, 122, 59 },
225 { 102, 39, 81, 18, 123, 60 }, { 103, 40, 82, 19, 124, 61 },
226 { 104, 41, 83, 20, 125, 62 }, { 105, 42, 84, 21, 0, 63 },
227 { 106, 43, 85, 22, 1, 64 }, { 107, 44, 86, 23, 2, 65 },
228 { 108, 45, 87, 24, 3, 66 }, { 109, 46, 88, 25, 4, 67 },
229 { 110, 47, 89, 26, 5, 68 }, { 111, 48, 90, 27, 6, 69 },
230 { 112, 49, 91, 28, 7, 70 }, { 113, 50, 92, 29, 8, 71 },
231 { 114, 51, 93, 30, 9, 72 }, { 115, 52, 94, 31, 10, 73 },
232 { 116, 53, 95, 32, 11, 74 }, { 117, 54, 96, 33, 12, 75 },
233 { 118, 55, 97, 34, 13, 76 }, { 119, 56, 98, 35, 14, 77 },
234 { 120, 57, 99, 36, 15, 78 }, { 121, 58, 100, 37, 16, 79 },
235 { 122, 59, 101, 38, 17, 80 }, { 123, 60, 102, 39, 18, 81 },
236 { 124, 61, 103, 40, 19, 82 }, { 125, 62, 104, 41, 20, 83 }
237 };
238
239 } /* namespace dtv */
240 } /* namespace gr */
241