| 80 | |
| 81 | template<typename B> |
| 82 | void |
| 83 | Encoder_conv<B>::build_tables() |
| 84 | { |
| 85 | next_state_table.resize(2 * n_states); |
| 86 | output_table.resize(2 * n_states); |
| 87 | |
| 88 | for (int s = 0; s < n_states; s++) |
| 89 | { |
| 90 | for (int b = 0; b < 2; b++) |
| 91 | { |
| 92 | // full_reg: input bit in MSB position, then the shift register state |
| 93 | int full_reg = (b << n_ff) | s; |
| 94 | |
| 95 | // Next state: shift right by 1 (newest bit enters from left) |
| 96 | next_state_table[2 * s + b] = full_reg >> 1; |
| 97 | |
| 98 | // Compute output for each polynomial |
| 99 | int packed_output = 0; |
| 100 | for (int p = 0; p < n_poly; p++) |
| 101 | { |
| 102 | int masked = full_reg & poly[p]; |
| 103 | // popcount mod 2 |
| 104 | int bit = 0; |
| 105 | while (masked) |
| 106 | { |
| 107 | bit ^= (masked & 1); |
| 108 | masked >>= 1; |
| 109 | } |
| 110 | packed_output = (packed_output << 1) | bit; |
| 111 | } |
| 112 | output_table[2 * s + b] = packed_output; |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | template<typename B> |
| 118 | int |