diff --git a/src/dsp_common/carrier.rs b/src/dsp_common/carrier.rs index e835823..37b98c0 100644 --- a/src/dsp_common/carrier.rs +++ b/src/dsp_common/carrier.rs @@ -1,5 +1,7 @@ use cpal::Sample; -use tracing::{trace}; +use tracing::trace; + +use super::sample::PcmSample; const TAU: f64 = 2.0 * std::f64::consts::PI; @@ -11,47 +13,77 @@ pub struct TwoStateCarrier { phase_high: f64, } -type PcmSample = i64; - pub trait Carrier { fn byte_into_fsk_samples(&mut self, byte: &u8) -> Vec; + fn idle(&mut self) -> [PcmSample; 8]; } impl Carrier for TwoStateCarrier { + /// turn a u8 into bits &do FSK on the carrier for each, returning samples fn byte_into_fsk_samples(&mut self, byte: &u8) -> Vec { - let mut bits: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; - let mut out: Vec = vec![]; + //let mut bits: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; + let mut out: Vec = vec![]; - // MSb first - bits[0] = (byte ) & 1; - bits[1] = (byte >> 1) & 1; - bits[2] = (byte >> 2) & 1; - bits[3] = (byte >> 3) & 1; - bits[4] = (byte >> 4) & 1; - bits[5] = (byte >> 5) & 1; - bits[6] = (byte >> 6) & 1; - bits[7] = (byte >> 7) & 1; + // LSb first + // bits[0] = (byte ) & 1; + // bits[1] = (byte >> 1) & 1; + // bits[2] = (byte >> 2) & 1; + // bits[3] = (byte >> 3) & 1; + // bits[4] = (byte >> 4) & 1; + // bits[5] = (byte >> 5) & 1; + // bits[6] = (byte >> 6) & 1; + // bits[7] = (byte >> 7) & 1; - for (i, bit) in bits.into_iter().enumerate() { - if bit == 0 { - trace!("low bit {} in fsk code", i); + // for each bit in the byte (LSb..=MSb)... + for bit_place in 1..=8 { + // if the bit is high... + if (byte >> bit_place) & 1 == 0 { + // while the signal hasn't yet completed a single period... while (self.phase_low) < self.sample_rate / self.freq_low { - out.push((self.phase_low * TAU * self.freq_low / self.sample_rate).sin().to_sample::()); + // push the next sample of the relative sine wave + out.push(PcmSample::F64( + (self.phase_low * TAU * self.freq_low + / self.sample_rate) + .sin(), + )); + // next sample self.phase_low += 1.0; } - self.phase_low = self.phase_low % (self.sample_rate / self.freq_high); - } else if bit == 1 { - trace!("high bit {} in fsk code", i); + // if phase counter exceeds 1 period, drop it down again + self.phase_low = + self.phase_low % (self.sample_rate / self.freq_low); + } else if (byte >> bit_place) & 1 == 1 { while (self.phase_high) < self.sample_rate / self.freq_high { - out.push((self.phase_high * TAU * self.freq_low / self.sample_rate).sin().to_sample::()); + out.push(PcmSample::F64( + (self.phase_high * TAU * self.freq_high + / self.sample_rate) + .sin(), + )); self.phase_high += 1.0; } - self.phase_high = self.phase_high % (self.sample_rate / self.freq_low); + self.phase_high = + self.phase_high % (self.sample_rate / self.freq_high); + } else { + // this keeps happening + unreachable!("FSK bit math returned a value that isn't 0 or 1"); } } //trace!("FSK calculations turned up {:?}", &out); out } + + fn idle(&mut self) -> [PcmSample; 8] { + const INIT_VALUE: PcmSample = PcmSample::F64(0.0); + let mut out: [PcmSample; 8] = [INIT_VALUE; 8]; + for i in 0..=7 { + out[i] = PcmSample::F64( + (self.phase_low * TAU * self.freq_low/ self.sample_rate).sin() + ); + self.phase_low += 1.0; + } + self.phase_low = self.phase_low % (self.sample_rate / self.freq_low); + out + } } impl TwoStateCarrier { @@ -64,6 +96,7 @@ impl TwoStateCarrier { phase_high: 0_f64, } } + // setters fn freq_low(mut self, freq_low: u32) { self.freq_low = freq_low.into(); } diff --git a/src/dsp_common/mod.rs b/src/dsp_common/mod.rs index 8fe1f10..16bed84 100644 --- a/src/dsp_common/mod.rs +++ b/src/dsp_common/mod.rs @@ -1 +1,2 @@ pub mod carrier; +pub mod sample; diff --git a/src/dsp_common/sample.rs b/src/dsp_common/sample.rs new file mode 100644 index 0000000..042cd31 --- /dev/null +++ b/src/dsp_common/sample.rs @@ -0,0 +1,11 @@ +#[derive(Copy)] +pub enum PcmSample { + U8(u8), + I8(i8), + U16(u16), + I32(i32), + F32(f32), + F64(f64), + U64(u64), + I64(i64), +} diff --git a/src/task_msg.rs b/src/task_msg.rs index 371f539..69e8058 100644 --- a/src/task_msg.rs +++ b/src/task_msg.rs @@ -1,3 +1,3 @@ -pub type PcmFrameMessage = Vec; +pub type PcmFrameMessage = Vec; pub type PcmSampleMessage = i64; pub type RawEthFrameMessage = Vec;