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