fec::{self, p_1, p_2, p_3},
interleave::interleave,
protocol::{
- LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, LSF_SYNC, PACKET_SYNC,
- STREAM_SYNC,
+ LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, END_OF_TRANSMISSION,
+ LSF_SYNC, PACKET_SYNC, PREAMBLE, STREAM_SYNC,
},
random::random_xor,
};
Bert,
Stream,
Packet,
+ Preamble,
+ EndOfTransmission,
}
impl SyncBurst {
Self::Bert => BERT_SYNC,
Self::Stream => STREAM_SYNC,
Self::Packet => PACKET_SYNC,
+ Self::Preamble => PREAMBLE,
+ Self::EndOfTransmission => END_OF_TRANSMISSION,
}
}
}
sample: u64,
/// Remaining samples to read in before attempting to decode the current candidate
samples_until_decode: Option<u16>,
+ /// Do we think there is a data carrier, i.e., channel in use? If so, at what sample does it expire?
+ dcd: Option<u64>,
}
impl SoftDemodulator {
candidate: None,
sample: 0,
samples_until_decode: None,
+ dcd: None,
+ }
+ }
+}
+
+impl SoftDemodulator {
+ fn dcd_until(&mut self, end_sample: u64) {
+ if self.dcd.is_none() {
+ debug!("SoftDemodulator DCD on");
+ }
+ self.dcd = Some(end_sample);
+ }
+
+ fn check_dcd(&mut self) {
+ if let Some(end_sample) = self.dcd {
+ if self.sample > end_sample {
+ self.dcd = None;
+ debug!("SoftDemodulator DCD off");
+ }
}
}
}
self.rx_cursor = (self.rx_cursor + 1) % 1920;
self.sample += 1;
+ self.check_dcd();
if let Some(samples_until_decode) = self.samples_until_decode {
let sud = samples_until_decode - 1;
return Some(Frame::Packet(frame));
}
}
+ SyncBurst::Preamble | SyncBurst::EndOfTransmission => {
+ // should never be chosen as a candidate
+ }
}
}
}
burst_window[i] = self.rx_win[c];
}
+ for burst in [SyncBurst::Preamble, SyncBurst::EndOfTransmission] {
+ let (diff, _, _) = sync_burst_correlation(burst.target(), &burst_window);
+ if diff < SYNC_THRESHOLD {
+ // arbitrary choice, 240 samples = 5ms
+ // these bursts keep repeating so it will keep pushing out the DCD end time
+ self.dcd_until(self.sample + 240);
+ }
+ }
+
for burst in [
SyncBurst::Lsf,
SyncBurst::Bert,
self.sample - c.age as u64,
c.diff
);
+ // After any of these frame types you would expect to see a full EOT
+ self.dcd_until(self.sample + 1920 + 1920);
}
}
pub(crate) const BERT_SYNC: [i8; 8] = [-1, 1, -1, -1, 1, 1, 1, 1];
pub(crate) const STREAM_SYNC: [i8; 8] = [-1, -1, -1, -1, 1, 1, -1, 1];
pub(crate) const PACKET_SYNC: [i8; 8] = [1, -1, 1, 1, -1, -1, -1, -1];
+pub(crate) const PREAMBLE: [i8; 8] = [1, -1, 1, -1, 1, -1, 1, -1];
+pub(crate) const END_OF_TRANSMISSION: [i8; 8] = [1, 1, 1, 1, 1, 1, -1, 1];
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum Mode {