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