]>
code.octet-stream.net Git - m17rt/blob - m17core/src/fec.rs
0716be0a38ab4e804cd216001b7d2aab8b25d170
1 use crate::bits
::{Bits
, BitsMut
};
10 static TRANSITIONS
: [Transition
; 32] = [
173 pub(crate) fn p_1(step
: usize) -> (bool
, bool
) {
174 let mod61
= step
% 61;
175 let is_even
= mod61
% 2 == 0;
176 (mod61
> 30 || is_even
, mod61
< 30 || is_even
)
179 pub(crate) fn p_2(step
: usize) -> (bool
, bool
) {
184 pub(crate) fn p_3(step
: usize) -> (bool
, bool
) {
189 fn best_previous(table
: &[[u8; 32]; 244], step
: usize, state
: usize) -> u8 {
197 let prev1
= table
[step
- 1][state
* 2];
198 let prev2
= table
[step
- 1][state
* 2 + 1];
202 fn hamming_distance(first
: &[u8], second
: &[u8]) -> u8 {
206 .map(|(x
, y
)| if *x
== *y
{ 0 } else { 1 })
210 // maximum 368 type 3 bits, maximum 240 type 1 bits, 4 flush bits
211 pub(crate) fn decode(
212 type3
: &[u8], // up to len 46
214 puncture
: fn(usize) -> (bool
, bool
),
215 ) -> Option
<[u8; 30]> {
216 let type3_bits
= Bits
::new(type3
);
217 let mut type3_iter
= type3_bits
.iter
();
218 let mut table
= [[0u8; 32]; 244];
219 for step
in 0..(input_len
+ 4) {
220 let (use_g1
, use_g2
) = puncture(step
);
221 let split_idx
= if use_g1
&& use_g2
{ 2 } else { 1 };
222 let mut input_bits
= [0u8; 2];
223 input_bits
[0] = type3_iter
.next().unwrap
();
224 let step_input
= if split_idx
== 1 {
227 input_bits
[1] = type3_iter
.next().unwrap
();
230 for (t_idx
, t
) in TRANSITIONS
.iter
().enumerate() {
231 let t_offer
= if use_g1
&& use_g2
{
238 let step_dist
= hamming_distance(step_input
, t_offer
);
239 table
[step
][t_idx
] = best_previous(&table
, step
, t
.source
).saturating_add(step_dist
);
242 let (mut best_idx
, best
) = table
[input_len
+ 3]
245 .min_by_key(|(_
, i
)| *i
)
247 debug
!("Best score is {best}, transition {best_idx}");
251 let mut out
= [0u8; 30];
252 let mut out_bits
= BitsMut
::new(&mut out
);
253 for step
in (0..(input_len
+ 4)).rev() {
254 let input
= TRANSITIONS
[best_idx
].inp
ut
;
255 if step
< input_len
{
256 out_bits
.set_bit(step
, input
);
259 let state
= TRANSITIONS
[best_idx
].source
;
260 let prev1
= table
[step
- 1][state
* 2];
261 let prev2
= table
[step
- 1][state
* 2 + 1];
262 best_idx
= if prev1
< prev2
{