2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * 'input' is 8-bits per symbol soft decision data
23 * 'len' is output byte length
30 static const struct ao_soft_sym ao_fec_decode_table[16] = {
32 { 0x00, 0x00 }, { 0xff, 0xff }, /* 000 */
33 { 0x00, 0xff }, { 0xff, 0x00 }, /* 001 */
34 { 0xff, 0xff }, { 0x00, 0x00 }, /* 010 */
35 { 0xff, 0x00 }, { 0x00, 0xff }, /* 011 */
36 { 0xff, 0xff }, { 0x00, 0x00 }, /* 100 */
37 { 0xff, 0x00 }, { 0x00, 0xff }, /* 101 */
38 { 0x00, 0x00 }, { 0xff, 0xff }, /* 110 */
39 { 0x00, 0xff }, { 0xff, 0x00 } /* 111 */
43 ao_soft_sym(uint8_t bits)
47 s.a = ((bits & 2) >> 1) * 0xff;
48 s.b = (bits & 1) * 0xff;
53 ao_next_state(uint8_t state, uint8_t bit)
55 return ((state << 1) | bit) & 0x7;
58 static inline abs(int x) { return x < 0 ? -x : x; }
60 static inline uint16_t
61 ao_cost(struct ao_soft_sym a, struct ao_soft_sym b)
63 return abs(a.a - b.a) + abs(a.b - b.b);
69 ao_fec_decode(uint8_t *in, int len, uint8_t *out)
71 uint16_t cost[2][NUM_STATE];
72 uint8_t prev[len/2 + 1][NUM_STATE];
76 uint8_t state = 0, min_state;
80 for (c = 0; c < NUM_STATE; c++)
84 for (i = 0; i < len; i += 2) {
87 struct ao_soft_sym s = { .a = in[i], .b = in[i+1] };
89 for (state = 0; state < NUM_STATE; state++)
90 cost[n][state] = 0xffff;
92 for (state = 0; state < NUM_STATE; state++) {
93 int zero_cost = ao_cost(s, ao_fec_decode_table[state * 2 + 0]);
94 int one_cost = ao_cost(s, ao_fec_decode_table[state * 2 + 1]);
96 uint8_t zero_state = ao_next_state(state, 0);
97 uint8_t one_state = ao_next_state(state, 1);
99 zero_cost += cost[p][state];
100 one_cost += cost[p][state];
101 if (zero_cost < cost[n][zero_state]) {
102 prev[b+1][zero_state] = state;
103 cost[n][zero_state] = zero_cost;
106 if (one_cost < cost[n][one_state]) {
107 prev[b+1][one_state] = state;
108 cost[n][one_state] = one_cost;
112 printf ("bit %3d symbol %2x %2x:", i/2, s.a, s.b);
113 for (state = 0; state < NUM_STATE; state++) {
114 printf (" %5d", cost[n][state]);
122 for (state = 1; state < NUM_STATE; state++) {
123 if (cost[p][state] < c) {
129 for (b = len/2; b > 0; b--) {
130 bits[b-1] = min_state & 1;
131 min_state = prev[b][min_state];
134 for (i = 0; i < len/2; i += 8) {
138 for (b = 0; b < 8; b++)
139 byte = (byte << 1) | bits[i + b];