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.
26 #include <ao_profile.h>
28 uint32_t ao_fec_decode_start, ao_fec_decode_end;
32 * byte order repeats through 3 2 1 0
34 * bit-pair order repeats through
38 * So, the over all order is:
40 * 3,1/0 2,1/0 1,1/0 0,1/0
41 * 3,3/2 2,3/2 1,3/2 0,3/2
42 * 3,5/4 2,5/4 1,5/4 0,5/4
43 * 3,7/6 2,7/6 1,7/6 0,7/6
45 * The raw bit order is thus
47 * 1e/1f 16/17 0e/0f 06/07
48 * 1c/1d 14/15 0c/0d 04/05
49 * 1a/1b 12/13 0a/0b 02/03
50 * 18/19 10/11 08/09 00/01
53 static const uint8_t ao_interleave_order[] = {
54 0x1e, 0x16, 0x0e, 0x06,
55 0x1c, 0x14, 0x0c, 0x04,
56 0x1a, 0x12, 0x0a, 0x02,
57 0x18, 0x10, 0x08, 0x00
60 static inline uint16_t ao_interleave_index(uint16_t i) {
61 return (i & ~0x1e) | ao_interleave_order[(i & 0x1e) >> 1];
71 * These are just the 'zero' states; the 'one' states mirror them
73 static const uint8_t ao_fec_decode_table[NUM_STATE*2] = {
85 ao_next_state(uint8_t state, uint8_t bit)
87 return ((state << 1) | bit) & 0x7;
91 * 'in' is 8-bits per symbol soft decision data
92 * 'len' is input byte length. 'out' must be
97 ao_fec_decode(const uint8_t *in, uint16_t len, uint8_t *out, uint8_t out_len, uint16_t (*callback)())
99 static uint32_t cost[2][NUM_STATE]; /* path cost */
100 static uint16_t bits[2][NUM_STATE]; /* save bits to quickly output them */
102 uint16_t i; /* input byte index */
103 uint16_t b; /* encoded symbol index (bytes/2) */
104 uint16_t o; /* output bit index */
105 uint8_t p; /* previous cost/bits index */
106 uint8_t n; /* next cost/bits index */
107 uint8_t state; /* state index */
108 const uint8_t *whiten = ao_fec_whiten_table;
109 uint16_t interleave; /* input byte array index */
112 uint16_t crc = AO_FEC_CRC_INIT;
118 for (state = 0; state < NUM_STATE; state++) {
119 cost[0][state] = 0x7fffffff;
135 start_tick = ao_profile_tick();
138 for (i = 0; i < len; i += 2) {
148 /* Fetch one pair of input bytes, de-interleaving
151 interleave = ao_interleave_index(i);
153 s1 = in[interleave+1];
157 /* Reset next costs to 'impossibly high' values so that
158 * the first path through this state is cheaper than this
160 for (state = 0; state < NUM_STATE; state++)
161 cost[n][state] = 0x7fffffff;
163 /* Compute path costs and accumulate output bit path
164 * for each state and encoded bit value
166 for (state = 0; state < NUM_STATE; state++) {
167 uint32_t bitcost = ((uint32_t) (s0 ^ ao_fec_decode_table[(state<<1)]) +
168 (uint32_t) (s1 ^ ao_fec_decode_table[(state<<1)+1]));
170 uint32_t cost0 = cost[p][state] + bitcost;
171 uint8_t state0 = ao_next_state(state, 0);
173 if (cost0 < cost[n][state0]) {
174 cost[n][state0] = cost0;
175 bits[n][state0] = (bits[p][state] << 1) | (state & 1);
179 uint32_t cost1 = cost[p][state] + 510 - bitcost;
180 uint8_t state1 = ao_next_state(state, 1);
182 if (cost1 < cost[n][state1]) {
183 cost[n][state1] = cost1;
184 bits[n][state1] = (bits[p][state] << 1) | (state & 1);
190 printf ("bit %3d symbol %2x %2x:", i/2, s0, s1);
191 for (state = 0; state < NUM_STATE; state++) {
192 printf (" %5d(%04x)", cost[n][state], bits[n][state]);
198 /* A loop is needed to handle the last output byte. It
199 * won't have any bits of future data to perform full
200 * error correction, but we might as well give the
201 * best possible answer anyways.
203 while ((b - o) >= (8 + NUM_HIST) || (i + 2 >= len && b > o)) {
205 /* Compute number of bits to the end of the
206 * last full byte of data. This is generally
207 * NUM_HIST, unless we've reached
208 * the end of the input, in which case
211 int8_t dist = b - (o + 8); /* distance to last ready-for-writing bit */
212 uint32_t min_cost; /* lowest cost */
213 uint8_t min_state; /* lowest cost state */
215 /* Find the best fit at the current point
218 min_cost = cost[p][0];
220 for (state = 1; state < NUM_STATE; state++) {
221 if (cost[p][state] < min_cost) {
222 min_cost = cost[p][state];
227 /* The very last byte of data has the very last bit
228 * of data left in the state value; just smash the
229 * bits value in place and reset the 'dist' from
230 * -1 to 0 so that the full byte is read out
233 bits[p][min_state] = (bits[p][min_state] << 1) | (min_state & 1);
238 printf ("\tbit %3d min_cost %5d old bit %3d old_state %x bits %02x whiten %0x\n",
239 i/2, min_cost, o + 8, min_state, (bits[p][min_state] >> dist) & 0xff, *whiten);
242 uint8_t byte = (bits[p][min_state] >> dist) ^ *whiten++;
245 crc = ao_fec_crc_byte(byte, crc);
248 *out++ = byte ^ (crc >> 8);
257 ao_fec_decode_start = start_tick;
258 ao_fec_decode_end = ao_profile_tick();