]>
code.octet-stream.net Git - m17rt/blob - m17core/src/decode.rs
3 fec
::{self, p_1
, p_2
, p_3
},
4 interleave
::interleave
,
6 LsfFrame
, PacketFrame
, PacketFrameCounter
, StreamFrame
, BERT_SYNC
, LSF_SYNC
, PACKET_SYNC
,
13 const PLUS_THREE
: [u8; 2] = [0, 1];
14 const PLUS_ONE
: [u8; 2] = [0, 0];
15 const MINUS_ONE
: [u8; 2] = [1, 0];
16 const MINUS_THREE
: [u8; 2] = [1, 1];
18 fn decode_sample(sample
: f32) -> [u8; 2] {
21 } else if sample
> 0.0 {
23 } else if sample
> -0.667 {
30 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
31 pub(crate) enum SyncBurst
{
39 pub(crate) fn target(&self) -> [i8; 8] {
41 Self::Lsf
=> LSF_SYNC
,
42 Self::Bert
=> BERT_SYNC
,
43 Self::Stream
=> STREAM_SYNC
,
44 Self::Packet
=> PACKET_SYNC
,
49 const SYNC_MIN_GAIN
: f32 = 16.0;
50 const SYNC_BIT_THRESHOLD
: f32 = 0.3;
51 pub const SYNC_THRESHOLD
: f32 = 100.0;
53 pub(crate) fn sync_burst_correlation(target
: [i8; 8], samples
: &[f32]) -> (f32, f32, f32) {
54 let mut pos_max
: f32 = f32::MIN
;
55 let mut neg_max
: f32 = f32::MAX
;
57 pos_max
= pos_max
.max(samples
[i
* 10]);
58 neg_max
= neg_max
.min(samples
[i
* 10]);
60 let gain
= (pos_max
- neg_max
) / 2.0;
61 let shift
= pos_max
+ neg_max
;
62 if gain
< SYNC_MIN_GAIN
{
63 return (f32::MAX
, gain
, shift
);
67 let sym_diff
= (((samples
[i
* 10] - shift
) / gain
) - target
[i
] as f32).abs();
68 if sym_diff
> SYNC_BIT_THRESHOLD
{
69 return (f32::MAX
, gain
, shift
);
76 /// Decode frame and return contents after the sync burst
77 pub(crate) fn frame_initial_decode(frame
: &[f32] /* length 192 */) -> [u8; 46] {
78 let mut decoded
= [0u8; 48];
79 let mut decoded_bits
= BitsMut
::new(&mut decoded
);
80 for (idx
, s
) in frame
.iter
().enumerate() {
81 let dibits
= decode_sample(*s
);
82 decoded_bits
.set_bit(idx
* 2, dibits
[0]);
83 decoded_bits
.set_bit(idx
* 2 + 1, dibits
[1]);
85 random_xor(&mut decoded
[2..]);
86 interleave(&decoded
[2..])
89 pub(crate) fn parse_lsf(frame
: &[f32] /* length 192 */) -> Option
<LsfFrame
> {
90 let deinterleaved
= frame_initial_decode(frame
);
91 let lsf
= match fec
::decode(&deinterleaved
, 240, p_1
) {
92 Some(lsf
) => LsfFrame(lsf
),
95 debug
!("full lsf: {:?}", lsf
.0);
97 debug
!("recv crc: {:04X}", crc
);
98 debug
!("destination: {:?}", lsf
.destination());
99 debug
!("source: {:?}", lsf
.source());
100 debug
!("mode: {:?}", lsf
.mode());
101 debug
!("data type: {:?}", lsf
.data_type());
102 debug
!("encryption type: {:?}", lsf
.encryption_type());
103 debug
!("can: {}", lsf
.channel_access_number());
104 debug
!("meta: {:?}", lsf
.meta());
108 pub(crate) fn try_lich_decode(type2_bits
: &[u8]) -> Option
<(u8, [u8; 5])> {
109 let mut decoded
= 0u64;
110 for (input_idx
, input_bytes
) in type2_bits
.chunks(3).enumerate() {
111 let mut input
: u32 = 0;
112 for (idx
, byte
) in input_bytes
.iter
().enumerate() {
113 input
|= (*byte
as u32) << (16 - (8 * idx
));
115 let (val
, _dist
) = cai_golay
::extended
::decode(input
)?
;
116 decoded
|= (val
as u64) << ((3 - input_idx
) * 12);
118 let b
= decoded
.to_be_bytes();
119 Some((b
[7] >> 5, [b
[2], b
[3], b
[4], b
[5], b
[6]]))
122 pub(crate) fn parse_stream(frame
: &[f32] /* length 192 */) -> Option
<StreamFrame
> {
123 let deinterleaved
= frame_initial_decode(frame
);
124 let stream_part
= &deinterleaved
[12..];
125 let stream
= match fec
::decode(stream_part
, 144, p_2
) {
126 Some(stream
) => stream
,
129 let frame_num
= u16::from_be_bytes([stream
[0], stream
[1]]);
130 let eos
= (frame_num
& 0x8000) > 0;
131 let frame_num
= frame_num
& 0x7fff; // higher layer has to handle wraparound
132 debug
!("frame number: {frame_num}, codec2: {:?}", &stream
[2..18]);
134 if let Some((counter
, part
)) = try_lich_decode(&deinterleaved
[0..12]) {
135 debug
!("LICH: received part {counter}");
139 frame_number
: frame_num
,
141 stream_data
: stream
[2..18].try_into().unwrap
(),
148 pub(crate) fn parse_packet(frame
: &[f32] /* length 192 */) -> Option
<PacketFrame
> {
149 let deinterleaved
= frame_initial_decode(frame
);
150 let packet
= match fec
::decode(&deinterleaved
, 206, p_3
) {
151 Some(packet
) => packet
,
154 let final_frame
= (packet
[25] & 0x80) > 0;
155 let number
= (packet
[25] >> 2) & 0x01f;
156 let counter
= if final_frame
{
157 PacketFrameCounter
::FinalFrame
{
158 payload_len
: number
as usize,
161 PacketFrameCounter
::Frame
{
162 index
: number
as usize,
166 payload
: packet
[0..25].try_into().unwrap
(),