]>
code.octet-stream.net Git - m17rt/blob - m17core/src/fec.rs
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 fn best_previous(table
: &[[u8; 32]; 244], step
: usize, state
: usize) -> u8 {
192 let prev1
= table
[step
- 1][state
* 2];
193 let prev2
= table
[step
- 1][state
* 2 + 1];
197 fn hamming_distance(first
: &[u8], second
: &[u8]) -> u8 {
201 .map(|(x
, y
)| if *x
== *y
{ 0 } else { 1 })
205 // maximum 368 type 3 bits, maximum 240 type 1 bits, 4 flush bits
206 pub(crate) fn decode(
207 type3
: &[u8], // up to len 46
209 puncture
: fn(usize) -> (bool
, bool
),
210 ) -> Option
<[u8; 30]> {
211 let type3_bits
= Bits
::new(type3
);
212 let mut type3_iter
= type3_bits
.iter
();
213 let mut table
= [[0u8; 32]; 244];
214 for step
in 0..(input_len
+ 4) {
215 let (use_g1
, use_g2
) = puncture(step
);
216 let split_idx
= if use_g1
&& use_g2
{ 2 } else { 1 };
217 let mut input_bits
= [0u8; 2];
218 input_bits
[0] = type3_iter
.next().unwrap
();
219 let step_input
= if split_idx
== 1 {
222 input_bits
[1] = type3_iter
.next().unwrap
();
225 for (t_idx
, t
) in TRANSITIONS
.iter
().enumerate() {
226 let t_offer
= if use_g1
&& use_g2
{
233 let step_dist
= hamming_distance(step_input
, t_offer
);
234 table
[step
][t_idx
] = best_previous(&table
, step
, t
.source
).saturating_add(step_dist
);
237 let (mut best_idx
, best
) = table
[input_len
+ 3]
240 .min_by_key(|(_
, i
)| *i
)
242 debug
!("Best score is {best}, transition {best_idx}");
246 let mut out
= [0u8; 30];
247 let mut out_bits
= BitsMut
::new(&mut out
);
248 for step
in (0..(input_len
+ 4)).rev() {
249 let input
= TRANSITIONS
[best_idx
].inp
ut
;
250 if step
< input_len
{
251 out_bits
.set_bit(step
, input
);
254 let state
= TRANSITIONS
[best_idx
].source
;
255 let prev1
= table
[step
- 1][state
* 2];
256 let prev2
= table
[step
- 1][state
* 2 + 1];
257 best_idx
= if prev1
< prev2
{