1 /* -*- c++ -*- */
2 /*
3 * Copyright 2015,2016,2018,2019 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 "dvb_bch_bb_impl.h"
26 #include <gnuradio/io_signature.h>
27
28 namespace gr {
29 namespace dtv {
30
31 dvb_bch_bb::sptr
make(dvb_standard_t standard,dvb_framesize_t framesize,dvb_code_rate_t rate)32 dvb_bch_bb::make(dvb_standard_t standard, dvb_framesize_t framesize, dvb_code_rate_t rate)
33 {
34 return gnuradio::get_initial_sptr(new dvb_bch_bb_impl(standard, framesize, rate));
35 }
36
37 /*
38 * The private constructor
39 */
dvb_bch_bb_impl(dvb_standard_t standard,dvb_framesize_t framesize,dvb_code_rate_t rate)40 dvb_bch_bb_impl::dvb_bch_bb_impl(dvb_standard_t standard,
41 dvb_framesize_t framesize,
42 dvb_code_rate_t rate)
43 : gr::block("dvb_bch_bb",
44 gr::io_signature::make(1, 1, sizeof(unsigned char)),
45 gr::io_signature::make(1, 1, sizeof(unsigned char)))
46 {
47 if (framesize == FECFRAME_NORMAL) {
48 switch (rate) {
49 case C1_4:
50 kbch = 16008;
51 nbch = 16200;
52 bch_code = BCH_CODE_N12;
53 break;
54 case C1_3:
55 kbch = 21408;
56 nbch = 21600;
57 bch_code = BCH_CODE_N12;
58 break;
59 case C2_5:
60 kbch = 25728;
61 nbch = 25920;
62 bch_code = BCH_CODE_N12;
63 break;
64 case C1_2:
65 kbch = 32208;
66 nbch = 32400;
67 bch_code = BCH_CODE_N12;
68 break;
69 case C3_5:
70 kbch = 38688;
71 nbch = 38880;
72 bch_code = BCH_CODE_N12;
73 break;
74 case C2_3:
75 kbch = 43040;
76 nbch = 43200;
77 bch_code = BCH_CODE_N10;
78 break;
79 case C3_4:
80 kbch = 48408;
81 nbch = 48600;
82 bch_code = BCH_CODE_N12;
83 break;
84 case C4_5:
85 kbch = 51648;
86 nbch = 51840;
87 bch_code = BCH_CODE_N12;
88 break;
89 case C5_6:
90 kbch = 53840;
91 nbch = 54000;
92 bch_code = BCH_CODE_N10;
93 break;
94 case C8_9:
95 kbch = 57472;
96 nbch = 57600;
97 bch_code = BCH_CODE_N8;
98 break;
99 case C9_10:
100 kbch = 58192;
101 nbch = 58320;
102 bch_code = BCH_CODE_N8;
103 break;
104 case C2_9_VLSNR:
105 kbch = 14208;
106 nbch = 14400;
107 bch_code = BCH_CODE_N12;
108 break;
109 case C13_45:
110 kbch = 18528;
111 nbch = 18720;
112 bch_code = BCH_CODE_N12;
113 break;
114 case C9_20:
115 kbch = 28968;
116 nbch = 29160;
117 bch_code = BCH_CODE_N12;
118 break;
119 case C90_180:
120 kbch = 32208;
121 nbch = 32400;
122 bch_code = BCH_CODE_N12;
123 break;
124 case C96_180:
125 kbch = 34368;
126 nbch = 34560;
127 bch_code = BCH_CODE_N12;
128 break;
129 case C11_20:
130 kbch = 35448;
131 nbch = 35640;
132 bch_code = BCH_CODE_N12;
133 break;
134 case C100_180:
135 kbch = 35808;
136 nbch = 36000;
137 bch_code = BCH_CODE_N12;
138 break;
139 case C104_180:
140 kbch = 37248;
141 nbch = 37440;
142 bch_code = BCH_CODE_N12;
143 break;
144 case C26_45:
145 kbch = 37248;
146 nbch = 37440;
147 bch_code = BCH_CODE_N12;
148 break;
149 case C18_30:
150 kbch = 38688;
151 nbch = 38880;
152 bch_code = BCH_CODE_N12;
153 break;
154 case C28_45:
155 kbch = 40128;
156 nbch = 40320;
157 bch_code = BCH_CODE_N12;
158 break;
159 case C23_36:
160 kbch = 41208;
161 nbch = 41400;
162 bch_code = BCH_CODE_N12;
163 break;
164 case C116_180:
165 kbch = 41568;
166 nbch = 41760;
167 bch_code = BCH_CODE_N12;
168 break;
169 case C20_30:
170 kbch = 43008;
171 nbch = 43200;
172 bch_code = BCH_CODE_N12;
173 break;
174 case C124_180:
175 kbch = 44448;
176 nbch = 44640;
177 bch_code = BCH_CODE_N12;
178 break;
179 case C25_36:
180 kbch = 44808;
181 nbch = 45000;
182 bch_code = BCH_CODE_N12;
183 break;
184 case C128_180:
185 kbch = 45888;
186 nbch = 46080;
187 bch_code = BCH_CODE_N12;
188 break;
189 case C13_18:
190 kbch = 46608;
191 nbch = 46800;
192 bch_code = BCH_CODE_N12;
193 break;
194 case C132_180:
195 kbch = 47328;
196 nbch = 47520;
197 bch_code = BCH_CODE_N12;
198 break;
199 case C22_30:
200 kbch = 47328;
201 nbch = 47520;
202 bch_code = BCH_CODE_N12;
203 break;
204 case C135_180:
205 kbch = 48408;
206 nbch = 48600;
207 bch_code = BCH_CODE_N12;
208 break;
209 case C140_180:
210 kbch = 50208;
211 nbch = 50400;
212 bch_code = BCH_CODE_N12;
213 break;
214 case C7_9:
215 kbch = 50208;
216 nbch = 50400;
217 bch_code = BCH_CODE_N12;
218 break;
219 case C154_180:
220 kbch = 55248;
221 nbch = 55440;
222 bch_code = BCH_CODE_N12;
223 break;
224 default:
225 kbch = 0;
226 nbch = 0;
227 bch_code = 0;
228 break;
229 }
230 } else if (framesize == FECFRAME_SHORT) {
231 switch (rate) {
232 case C1_4:
233 kbch = 3072;
234 nbch = 3240;
235 bch_code = BCH_CODE_S12;
236 break;
237 case C1_3:
238 kbch = 5232;
239 nbch = 5400;
240 bch_code = BCH_CODE_S12;
241 break;
242 case C2_5:
243 kbch = 6312;
244 nbch = 6480;
245 bch_code = BCH_CODE_S12;
246 break;
247 case C1_2:
248 kbch = 7032;
249 nbch = 7200;
250 bch_code = BCH_CODE_S12;
251 break;
252 case C3_5:
253 kbch = 9552;
254 nbch = 9720;
255 bch_code = BCH_CODE_S12;
256 break;
257 case C2_3:
258 kbch = 10632;
259 nbch = 10800;
260 bch_code = BCH_CODE_S12;
261 break;
262 case C3_4:
263 kbch = 11712;
264 nbch = 11880;
265 bch_code = BCH_CODE_S12;
266 break;
267 case C4_5:
268 kbch = 12432;
269 nbch = 12600;
270 bch_code = BCH_CODE_S12;
271 break;
272 case C5_6:
273 kbch = 13152;
274 nbch = 13320;
275 bch_code = BCH_CODE_S12;
276 break;
277 case C8_9:
278 kbch = 14232;
279 nbch = 14400;
280 bch_code = BCH_CODE_S12;
281 break;
282 case C11_45:
283 kbch = 3792;
284 nbch = 3960;
285 bch_code = BCH_CODE_S12;
286 break;
287 case C4_15:
288 kbch = 4152;
289 nbch = 4320;
290 bch_code = BCH_CODE_S12;
291 break;
292 case C14_45:
293 kbch = 4872;
294 nbch = 5040;
295 bch_code = BCH_CODE_S12;
296 break;
297 case C7_15:
298 kbch = 7392;
299 nbch = 7560;
300 bch_code = BCH_CODE_S12;
301 break;
302 case C8_15:
303 kbch = 8472;
304 nbch = 8640;
305 bch_code = BCH_CODE_S12;
306 break;
307 case C26_45:
308 kbch = 9192;
309 nbch = 9360;
310 bch_code = BCH_CODE_S12;
311 break;
312 case C32_45:
313 kbch = 11352;
314 nbch = 11520;
315 bch_code = BCH_CODE_S12;
316 break;
317 case C1_5_VLSNR_SF2:
318 kbch = 2512;
319 nbch = 2680;
320 bch_code = BCH_CODE_S12;
321 break;
322 case C11_45_VLSNR_SF2:
323 kbch = 3792;
324 nbch = 3960;
325 bch_code = BCH_CODE_S12;
326 break;
327 case C1_5_VLSNR:
328 kbch = 3072;
329 nbch = 3240;
330 bch_code = BCH_CODE_S12;
331 break;
332 case C4_15_VLSNR:
333 kbch = 4152;
334 nbch = 4320;
335 bch_code = BCH_CODE_S12;
336 break;
337 case C1_3_VLSNR:
338 kbch = 5232;
339 nbch = 5400;
340 bch_code = BCH_CODE_S12;
341 break;
342 default:
343 kbch = 0;
344 nbch = 0;
345 bch_code = 0;
346 break;
347 }
348 } else {
349 switch (rate) {
350 case C1_5_MEDIUM:
351 kbch = 5660;
352 nbch = 5840;
353 bch_code = BCH_CODE_M12;
354 break;
355 case C11_45_MEDIUM:
356 kbch = 7740;
357 nbch = 7920;
358 bch_code = BCH_CODE_M12;
359 break;
360 case C1_3_MEDIUM:
361 kbch = 10620;
362 nbch = 10800;
363 bch_code = BCH_CODE_M12;
364 break;
365 default:
366 kbch = 0;
367 nbch = 0;
368 bch_code = 0;
369 break;
370 }
371 }
372
373 switch (bch_code) {
374 case BCH_CODE_N12:
375 num_parity_bits = 192;
376 break;
377 case BCH_CODE_N10:
378 num_parity_bits = 160;
379 break;
380 case BCH_CODE_N8:
381 num_parity_bits = 128;
382 break;
383 case BCH_CODE_M12:
384 num_parity_bits = 180;
385 break;
386 case BCH_CODE_S12:
387 num_parity_bits = 168;
388 break;
389 }
390
391 bch_poly_build_tables();
392 frame_size = framesize;
393 set_output_multiple(nbch);
394 }
395
396 /*
397 * Our virtual destructor.
398 */
~dvb_bch_bb_impl()399 dvb_bch_bb_impl::~dvb_bch_bb_impl() {}
400
forecast(int noutput_items,gr_vector_int & ninput_items_required)401 void dvb_bch_bb_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required)
402 {
403 ninput_items_required[0] = (noutput_items / nbch) * kbch;
404 }
405
406 /*
407 * Polynomial calculation routines
408 * multiply polynomials
409 */
poly_mult(const int * ina,int lena,const int * inb,int lenb,int * out)410 int dvb_bch_bb_impl::poly_mult(
411 const int* ina, int lena, const int* inb, int lenb, int* out)
412 {
413 memset(out, 0, sizeof(int) * (lena + lenb));
414
415 for (int i = 0; i < lena; i++) {
416 for (int j = 0; j < lenb; j++) {
417 if (ina[i] * inb[j] > 0) {
418 out[i + j]++; // count number of terms for this pwr of x
419 }
420 }
421 }
422 int max = 0;
423 for (int i = 0; i < lena + lenb; i++) {
424 out[i] = out[i] & 1; // If even ignore the term
425 if (out[i]) {
426 max = i;
427 }
428 }
429 // return the size of array to house the result.
430 return max + 1;
431 }
432
433 // precalculate the crc from:
434 // http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html - cf. CRC-32 Lookup
calculate_crc_table(void)435 void dvb_bch_bb_impl::calculate_crc_table(void)
436 {
437 for (int divident = 0; divident < 256;
438 divident++) { /* iterate over all possible input byte values 0 - 255 */
439 std::bitset<MAX_BCH_PARITY_BITS> curByte(divident);
440 curByte <<= num_parity_bits - 8;
441
442 for (unsigned char bit = 0; bit < 8; bit++) {
443 if ((curByte[num_parity_bits - 1]) != 0) {
444 curByte <<= 1;
445 curByte ^= polynome;
446 } else {
447 curByte <<= 1;
448 }
449 }
450 crc_table[divident] = curByte;
451 }
452 }
453
calculate_medium_crc_table(void)454 void dvb_bch_bb_impl::calculate_medium_crc_table(void)
455 {
456 for (int divident = 0; divident < 16;
457 divident++) { /* iterate over all possible input byte values 0 - 15 */
458 std::bitset<MAX_BCH_PARITY_BITS> curByte(divident);
459 curByte <<= num_parity_bits - 4;
460
461 for (unsigned char bit = 0; bit < 4; bit++) {
462 if ((curByte[num_parity_bits - 1]) != 0) {
463 curByte <<= 1;
464 curByte ^= polynome;
465 } else {
466 curByte <<= 1;
467 }
468 }
469 crc_medium_table[divident] = curByte;
470 }
471 }
472
bch_poly_build_tables(void)473 void dvb_bch_bb_impl::bch_poly_build_tables(void)
474 {
475 // Normal polynomials
476 const int polyn01[] = { 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
477 const int polyn02[] = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 };
478 const int polyn03[] = { 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 };
479 const int polyn04[] = { 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1 };
480 const int polyn05[] = { 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1 };
481 const int polyn06[] = { 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 };
482 const int polyn07[] = { 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1 };
483 const int polyn08[] = { 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1 };
484 const int polyn09[] = { 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 };
485 const int polyn10[] = { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 };
486 const int polyn11[] = { 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 };
487 const int polyn12[] = { 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1 };
488
489 // Medium polynomials
490 const int polym01[] = { 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
491 const int polym02[] = { 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1 };
492 const int polym03[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1 };
493 const int polym04[] = { 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1 };
494 const int polym05[] = { 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1 };
495 const int polym06[] = { 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
496 const int polym07[] = { 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1 };
497 const int polym08[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1 };
498 const int polym09[] = { 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 };
499 const int polym10[] = { 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1 };
500 const int polym11[] = { 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1 };
501 const int polym12[] = { 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1 };
502
503 // Short polynomials
504 const int polys01[] = { 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
505 const int polys02[] = { 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 };
506 const int polys03[] = { 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1 };
507 const int polys04[] = { 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1 };
508 const int polys05[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1 };
509 const int polys06[] = { 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 };
510 const int polys07[] = { 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1 };
511 const int polys08[] = { 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1 };
512 const int polys09[] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1 };
513 const int polys10[] = { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 };
514 const int polys11[] = { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1 };
515 const int polys12[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1 };
516
517 int len;
518 int polyout[2][200];
519
520 #define COPY_BCH_POLYNOME \
521 for (unsigned int i = 0; i < num_parity_bits; i++) { \
522 polynome[i] = polyout[0][i]; \
523 }
524
525 switch (bch_code) {
526 case BCH_CODE_N12:
527 case BCH_CODE_N10:
528 case BCH_CODE_N8:
529
530 len = poly_mult(polyn01, 17, polyn02, 17, polyout[0]);
531 len = poly_mult(polyn03, 17, polyout[0], len, polyout[1]);
532 len = poly_mult(polyn04, 17, polyout[1], len, polyout[0]);
533 len = poly_mult(polyn05, 17, polyout[0], len, polyout[1]);
534 len = poly_mult(polyn06, 17, polyout[1], len, polyout[0]);
535 len = poly_mult(polyn07, 17, polyout[0], len, polyout[1]);
536 len = poly_mult(polyn08, 17, polyout[1], len, polyout[0]);
537 if (bch_code == BCH_CODE_N8) {
538 COPY_BCH_POLYNOME
539 }
540
541 len = poly_mult(polyn09, 17, polyout[0], len, polyout[1]);
542 len = poly_mult(polyn10, 17, polyout[1], len, polyout[0]);
543 if (bch_code == BCH_CODE_N10) {
544 COPY_BCH_POLYNOME
545 }
546
547 len = poly_mult(polyn11, 17, polyout[0], len, polyout[1]);
548 len = poly_mult(polyn12, 17, polyout[1], len, polyout[0]);
549 if (bch_code == BCH_CODE_N12) {
550 COPY_BCH_POLYNOME
551 }
552 break;
553
554 case BCH_CODE_S12:
555 len = poly_mult(polys01, 15, polys02, 15, polyout[0]);
556 len = poly_mult(polys03, 15, polyout[0], len, polyout[1]);
557 len = poly_mult(polys04, 15, polyout[1], len, polyout[0]);
558 len = poly_mult(polys05, 15, polyout[0], len, polyout[1]);
559 len = poly_mult(polys06, 15, polyout[1], len, polyout[0]);
560 len = poly_mult(polys07, 15, polyout[0], len, polyout[1]);
561 len = poly_mult(polys08, 15, polyout[1], len, polyout[0]);
562 len = poly_mult(polys09, 15, polyout[0], len, polyout[1]);
563 len = poly_mult(polys10, 15, polyout[1], len, polyout[0]);
564 len = poly_mult(polys11, 15, polyout[0], len, polyout[1]);
565 len = poly_mult(polys12, 15, polyout[1], len, polyout[0]);
566
567 COPY_BCH_POLYNOME
568 break;
569
570 case BCH_CODE_M12:
571 len = poly_mult(polym01, 16, polym02, 16, polyout[0]);
572 len = poly_mult(polym03, 16, polyout[0], len, polyout[1]);
573 len = poly_mult(polym04, 16, polyout[1], len, polyout[0]);
574 len = poly_mult(polym05, 16, polyout[0], len, polyout[1]);
575 len = poly_mult(polym06, 16, polyout[1], len, polyout[0]);
576 len = poly_mult(polym07, 16, polyout[0], len, polyout[1]);
577 len = poly_mult(polym08, 16, polyout[1], len, polyout[0]);
578 len = poly_mult(polym09, 16, polyout[0], len, polyout[1]);
579 len = poly_mult(polym10, 16, polyout[1], len, polyout[0]);
580 len = poly_mult(polym11, 16, polyout[0], len, polyout[1]);
581 len = poly_mult(polym12, 16, polyout[1], len, polyout[0]);
582
583 COPY_BCH_POLYNOME
584 break;
585 }
586 calculate_crc_table();
587 calculate_medium_crc_table();
588 }
589
general_work(int noutput_items,gr_vector_int & ninput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)590 int dvb_bch_bb_impl::general_work(int noutput_items,
591 gr_vector_int& ninput_items,
592 gr_vector_const_void_star& input_items,
593 gr_vector_void_star& output_items)
594 {
595 const unsigned char* in = (const unsigned char*)input_items[0];
596 unsigned char* out = (unsigned char*)output_items[0];
597 unsigned char b, temp, msb;
598
599 // We can use a 192 bits long bitset, all higher bits not used by the bch will just be
600 // ignored
601 std::bitset<MAX_BCH_PARITY_BITS> parity_bits;
602 int consumed = 0;
603
604 if (frame_size != FECFRAME_MEDIUM) {
605 for (int i = 0; i < noutput_items; i += nbch) {
606 memcpy(out, in, sizeof(unsigned char) * kbch);
607 out += kbch;
608 for (int j = 0; j < (int)kbch / 8; j++) {
609 b = 0;
610
611 // calculate the crc using the lookup table, cf.
612 // http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
613 for (int e = 0; e < 8; e++) {
614 temp = *in++;
615 consumed++;
616
617 b |= temp << (7 - e);
618 }
619
620 msb = 0;
621 for (int n = 1; n <= 8; n++) {
622 temp = parity_bits[num_parity_bits - n];
623 msb |= temp << (8 - n);
624 }
625 /* XOR-in next input byte into MSB of crc and get this MSB, that's our new
626 * intermediate divident */
627 unsigned char pos = (msb ^ b);
628 /* Shift out the MSB used for division per lookuptable and XOR with the
629 * remainder */
630 parity_bits = (parity_bits << 8) ^ crc_table[pos];
631 }
632
633 // Now add the parity bits to the output
634 for (unsigned int n = 0; n < num_parity_bits; n++) {
635 *out++ = (char)parity_bits[num_parity_bits - 1];
636 parity_bits <<= 1;
637 }
638 }
639 } else {
640 for (int i = 0; i < noutput_items; i += nbch) {
641 memcpy(out, in, sizeof(unsigned char) * kbch);
642 out += kbch;
643 for (int j = 0; j < (int)kbch / 4; j++) {
644 b = 0;
645
646 // calculate the crc using the lookup table, cf.
647 // http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
648 for (int e = 0; e < 4; e++) {
649 temp = *in++;
650 consumed++;
651
652 b |= temp << (3 - e);
653 }
654
655 msb = 0;
656 for (int n = 1; n <= 4; n++) {
657 temp = parity_bits[num_parity_bits - n];
658 msb |= temp << (4 - n);
659 }
660 /* XOR-in next input byte into MSB of crc and get this MSB, that's our new
661 * intermediate divident */
662 unsigned char pos = (msb ^ b);
663 /* Shift out the MSB used for division per lookuptable and XOR with the
664 * remainder */
665 parity_bits = (parity_bits << 4) ^ crc_medium_table[pos];
666 }
667
668 // Now add the parity bits to the output
669 for (unsigned int n = 0; n < num_parity_bits; n++) {
670 *out++ = (char)parity_bits[num_parity_bits - 1];
671 parity_bits <<= 1;
672 }
673 }
674 }
675
676 // Tell runtime system how many input items we consumed on
677 // each input stream.
678 consume_each(consumed);
679
680 // Tell runtime system how many output items we produced.
681 return noutput_items;
682 }
683
684 } /* namespace dtv */
685 } /* namespace gr */
686