]> code.octet-stream.net Git - m17rt/blob - m17core/src/encode.rs
Encoding LICH and round trip tests
[m17rt] / m17core / src / encode.rs
1 use crate::{
2 bits::Bits,
3 fec::{self, p_1},
4 interleave::interleave,
5 protocol::{LsfFrame, PacketFrame, StreamFrame, LSF_SYNC},
6 random::random_xor,
7 };
8
9 pub(crate) fn encode_lsf(frame: &LsfFrame) -> [f32; 192] {
10 let type3 = fec::encode(&frame.0, 240, p_1);
11 let mut interleaved = interleave(&type3);
12 random_xor(&mut interleaved);
13 let mut out = [0f32; 192];
14 for (val, o) in LSF_SYNC.iter().zip(out.iter_mut()) {
15 *o = *val as f32;
16 }
17 let bits = Bits::new(&interleaved);
18 let mut out_bits = bits.iter();
19 for o in out[8..].iter_mut() {
20 *o = match (out_bits.next().unwrap(), out_bits.next().unwrap()) {
21 (0, 1) => 1.0,
22 (0, 0) => 1.0 / 3.0,
23 (1, 0) => -1.0 / 3.0,
24 (1, 1) => -1.0,
25 _ => unreachable!(),
26 };
27 }
28 out
29 }
30
31 /*pub(crate) fn encode_stream(frame: &StreamFrame) -> [f32; 192] {
32 let type3 = fec::encode(&frame.0, 240, p_1);
33 let mut interleaved = interleave(&type3);
34 random_xor(&mut interleaved);
35 let mut out = [0f32; 192];
36 for (val, o) in LSF_SYNC.iter().zip(out.iter_mut()) {
37 *o = *val as f32;
38 }
39 let bits = Bits::new(&interleaved);
40 let mut out_bits = bits.iter();
41 for o in out[8..].iter_mut() {
42 *o = match (out_bits.next().unwrap(), out_bits.next().unwrap()) {
43 (0, 1) => 1.0,
44 (0, 0) => 1.0 / 3.0,
45 (1, 0) => -1.0 / 3.0,
46 (1, 1) => -1.0,
47 _ => unreachable!(),
48 };
49 }
50 out
51 }*/
52
53 /*pub(crate) fn encode_packet(frame: &PacketFrame) -> [f32; 192] {
54 let type3 = fec::encode(&frame.0, 240, p_1);
55 let mut interleaved = interleave(&type3);
56 random_xor(&mut interleaved);
57 let mut out = [0f32; 192];
58 for (val, o) in LSF_SYNC.iter().zip(out.iter_mut()) {
59 *o = *val as f32;
60 }
61 let bits = Bits::new(&interleaved);
62 let mut out_bits = bits.iter();
63 for o in out[8..].iter_mut() {
64 *o = match (out_bits.next().unwrap(), out_bits.next().unwrap()) {
65 (0, 1) => 1.0,
66 (0, 0) => 1.0 / 3.0,
67 (1, 0) => -1.0 / 3.0,
68 (1, 1) => -1.0,
69 _ => unreachable!(),
70 };
71 }
72 out
73 }*/
74
75 pub(crate) fn encode_lich(counter: u8, part: [u8; 5]) -> [u8; 12] {
76 let mut out = [0u8; 12];
77 let to_encode = [
78 ((part[0] as u16) << 4) | ((part[1] as u16) >> 4),
79 ((part[1] as u16 & 0x000f) << 8) | part[2] as u16,
80 ((part[3] as u16) << 4) | ((part[4] as u16) >> 4),
81 ((part[4] as u16 & 0x000f) << 8) | ((counter as u16) << 5),
82 ];
83 for (i, o) in to_encode.into_iter().zip(out.chunks_mut(3)) {
84 let encoded = cai_golay::extended::encode(i).to_be_bytes();
85 o[0..3].copy_from_slice(&encoded[1..4]);
86 }
87 out
88 }
89
90 #[cfg(test)]
91 mod tests {
92 use super::*;
93
94 #[test]
95 fn lsf_round_trip() {
96 let lsf = LsfFrame([
97 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 131, 53,
99 ]);
100 let encoded = encode_lsf(&lsf);
101 let decoded = crate::decode::parse_lsf(&encoded);
102 assert_eq!(decoded, Some(lsf));
103 }
104
105 #[test]
106 fn lich_encode() {
107 let input = [221, 81, 5, 5, 0];
108 let counter = 2;
109 let expected_output = [221, 82, 162, 16, 85, 200, 5, 14, 254, 4, 13, 153];
110 assert_eq!(encode_lich(counter, input), expected_output);
111 }
112
113 #[test]
114 fn lich_round_trip() {
115 let input = [1, 255, 0, 90, 10];
116 let counter = 0;
117 assert_eq!(
118 crate::decode::decode_lich(&encode_lich(counter, input.clone())),
119 Some((counter, input))
120 );
121 }
122 }