]>
code.octet-stream.net Git - m17rt/blob - m17core/src/encode.rs
8f1d1da48a7b0ddcea63a13d5fab9209a3ee2dc7
3 fec
::{self, p_1
, p_2
, p_3
},
4 interleave
::interleave
,
6 LsfFrame
, PacketFrame
, PacketFrameCounter
, StreamFrame
, LSF_SYNC
, PACKET_SYNC
, STREAM_SYNC
,
11 pub(crate) fn encode_lsf(frame
: &LsfFrame
) -> [f32; 192] {
12 let type3
= fec
::encode(&frame
.0, 240, p_1
);
13 interleave_to_dibits(type3
, LSF_SYNC
)
16 pub(crate) fn encode_stream(frame
: &StreamFrame
) -> [f32; 192] {
17 let lich
= encode_lich(frame
.lich_idx
, &frame
.lich_part
);
18 let mut type1
= [0u8; 18];
19 let frame_number
= frame
.frame
_n
umber
| if frame
.end_of_stream
{ 0x8000 } else { 0x0000 };
20 type1
[0..2].copy_from_slice(&frame_number
.to_be_bytes());
21 type1
[2..18].copy_from_slice(&frame
.stream_data
);
22 let type3
= fec
::encode(&type1
, 144, p_2
);
23 let mut combined
= [0u8; 46];
24 combined
[0..12].copy_from_slice(&lich
);
25 combined
[12..46].copy_from_slice(&type3
[0..34]);
26 interleave_to_dibits(combined
, STREAM_SYNC
)
29 pub(crate) fn encode_packet(frame
: &PacketFrame
) -> [f32; 192] {
30 let mut type1
= [0u8; 26]; // only 206 out of 208 bits filled
32 PacketFrameCounter
::Frame
{ index
} => {
33 type1
[0..25].copy_from_slice(&frame
.payload
);
34 type1
[25] = (index
as u8) << 3;
36 PacketFrameCounter
::FinalFrame
{ payload_len
} => {
37 type1
[0..payload_len
].copy_from_slice(&frame
.payload
[0..payload_len
]);
38 type1
[25] = (payload_len
as u8) << 3 | 0x04;
41 let type3
= fec
::encode(&type1
, 206, p_3
);
42 interleave_to_dibits(type3
, PACKET_SYNC
)
45 /// Generate a preamble suitable for placement before an LSF frame.
47 /// Polarity needs to be flipped for BERT, however we don't support this yet.
48 /// STREAM and PACKET don't need to be considered as they are an invalid way to
49 /// begin a transmission.
50 pub(crate) fn generate_preamble() -> [f32; 192] {
51 // TODO: should all these encode/generate functions return owning iterators?
52 // Then I could avoid making this array which I'm just going to have to copy anyway
53 let mut out
= [1.0f32; 192];
54 for n
in out
.iter
_m
ut
().skip(1).step_by(2) {
60 pub(crate) fn generate_end_of_transmission() -> [f32; 192] {
61 let mut out
= [1.0f32; 192];
62 for n
in out
.iter
_m
ut
().skip(6).step_by(8) {
68 pub(crate) fn encode_lich(counter
: u8, part
: &[u8; 5]) -> [u8; 12] {
69 let mut out
= [0u8; 12];
71 ((part
[0] as u16) << 4) | ((part
[1] as u16) >> 4),
72 ((part
[1] as u16 & 0x000f) << 8) | part
[2] as u16,
73 ((part
[3] as u16) << 4) | ((part
[4] as u16) >> 4),
74 ((part
[4] as u16 & 0x000f) << 8) | ((counter
as u16) << 5),
76 for (i
, o
) in to_encode
.into
_iter
().zip(out
.chunks_mut(3)) {
77 let encoded
= cai_golay
::extended
::encode(i
).to_be_bytes();
78 o
[0..3].copy_from_slice(&encoded
[1..4]);
83 fn interleave_to_dibits(combined
: [u8; 46], sync_burst
: [i8; 8]) -> [f32; 192] {
84 let mut interleaved
= interleave(&combined
);
85 random_xor(&mut interleaved
);
86 let mut out
= [0f32; 192];
87 for (val
, o
) in sync_burst
.iter
().zip(out
.iter
_m
ut
()) {
90 let bits
= Bits
::new(&interleaved
);
91 let mut out_bits
= bits
.iter
();
92 for o
in out
[8..].iter
_m
ut
() {
93 *o
= match (out_bits
.next().unwrap
(), out_bits
.next().unwrap
()) {
109 fn lsf_round_trip() {
111 255, 255, 255, 255, 255, 255, 0, 0, 0, 159, 221, 81, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 131, 53,
114 let encoded
= encode_lsf(&lsf
);
115 let decoded
= crate::decode
::parse_lsf(&encoded
);
116 assert_eq
!(decoded
, Some(lsf
));
120 fn stream_round_trip() {
121 let stream
= StreamFrame
{
123 lich_part
: [1, 2, 3, 4, 5],
125 end_of_stream
: false,
126 stream_data
: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
128 let encoded
= encode_stream(&stream
);
129 let decoded
= crate::decode
::parse_stream(&encoded
);
130 assert_eq
!(decoded
, Some(stream
));
134 fn packet_round_trip() {
135 let packet
= PacketFrame
{
137 counter
: PacketFrameCounter
::Frame
{ index
: 3 },
139 let encoded
= encode_packet(&packet
);
140 let decoded
= crate::decode
::parse_packet(&encoded
);
141 assert_eq
!(decoded
, Some(packet
));
143 let packet
= PacketFrame
{
145 counter
: PacketFrameCounter
::FinalFrame
{ payload_len
: 10 },
147 let encoded
= encode_packet(&packet
);
148 let decoded
= crate::decode
::parse_packet(&encoded
);
149 assert_eq
!(decoded
, Some(packet
));
154 let input
= [221, 81, 5, 5, 0];
156 let expected_output
= [221, 82, 162, 16, 85, 200, 5, 14, 254, 4, 13, 153];
157 assert_eq
!(encode_lich(counter
, &input
), expected_output
);
161 fn lich_round_trip() {
162 let input
= [1, 255, 0, 90, 10];
165 crate::decode
::decode_lich(&encode_lich(counter
, &input
)),
166 Some((counter
, input
))