refactor 1 of 2 on dsp_common::carrier
This commit is contained in:
parent
bbcb3a6b2d
commit
bb283c6e47
4 changed files with 69 additions and 24 deletions
|
@ -1,5 +1,7 @@
|
||||||
use cpal::Sample;
|
use cpal::Sample;
|
||||||
use tracing::{trace};
|
use tracing::trace;
|
||||||
|
|
||||||
|
use super::sample::PcmSample;
|
||||||
|
|
||||||
const TAU: f64 = 2.0 * std::f64::consts::PI;
|
const TAU: f64 = 2.0 * std::f64::consts::PI;
|
||||||
|
|
||||||
|
@ -11,47 +13,77 @@ pub struct TwoStateCarrier {
|
||||||
phase_high: f64,
|
phase_high: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
type PcmSample = i64;
|
|
||||||
|
|
||||||
pub trait Carrier {
|
pub trait Carrier {
|
||||||
fn byte_into_fsk_samples(&mut self, byte: &u8) -> Vec<PcmSample>;
|
fn byte_into_fsk_samples(&mut self, byte: &u8) -> Vec<PcmSample>;
|
||||||
|
fn idle(&mut self) -> [PcmSample; 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Carrier for TwoStateCarrier {
|
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<PcmSample> {
|
fn byte_into_fsk_samples(&mut self, byte: &u8) -> Vec<PcmSample> {
|
||||||
let mut bits: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
//let mut bits: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
let mut out: Vec<i64> = vec![];
|
let mut out: Vec<PcmSample> = vec![];
|
||||||
|
|
||||||
// MSb first
|
// LSb first
|
||||||
bits[0] = (byte ) & 1;
|
// bits[0] = (byte ) & 1;
|
||||||
bits[1] = (byte >> 1) & 1;
|
// bits[1] = (byte >> 1) & 1;
|
||||||
bits[2] = (byte >> 2) & 1;
|
// bits[2] = (byte >> 2) & 1;
|
||||||
bits[3] = (byte >> 3) & 1;
|
// bits[3] = (byte >> 3) & 1;
|
||||||
bits[4] = (byte >> 4) & 1;
|
// bits[4] = (byte >> 4) & 1;
|
||||||
bits[5] = (byte >> 5) & 1;
|
// bits[5] = (byte >> 5) & 1;
|
||||||
bits[6] = (byte >> 6) & 1;
|
// bits[6] = (byte >> 6) & 1;
|
||||||
bits[7] = (byte >> 7) & 1;
|
// bits[7] = (byte >> 7) & 1;
|
||||||
|
|
||||||
for (i, bit) in bits.into_iter().enumerate() {
|
// for each bit in the byte (LSb..=MSb)...
|
||||||
if bit == 0 {
|
for bit_place in 1..=8 {
|
||||||
trace!("low bit {} in fsk code", i);
|
// 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 {
|
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::<i64>());
|
// 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 += 1.0;
|
||||||
}
|
}
|
||||||
self.phase_low = self.phase_low % (self.sample_rate / self.freq_high);
|
// if phase counter exceeds 1 period, drop it down again
|
||||||
} else if bit == 1 {
|
self.phase_low =
|
||||||
trace!("high bit {} in fsk code", i);
|
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 {
|
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::<i64>());
|
out.push(PcmSample::F64(
|
||||||
|
(self.phase_high * TAU * self.freq_high
|
||||||
|
/ self.sample_rate)
|
||||||
|
.sin(),
|
||||||
|
));
|
||||||
self.phase_high += 1.0;
|
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);
|
//trace!("FSK calculations turned up {:?}", &out);
|
||||||
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 {
|
impl TwoStateCarrier {
|
||||||
|
@ -64,6 +96,7 @@ impl TwoStateCarrier {
|
||||||
phase_high: 0_f64,
|
phase_high: 0_f64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// setters
|
||||||
fn freq_low(mut self, freq_low: u32) {
|
fn freq_low(mut self, freq_low: u32) {
|
||||||
self.freq_low = freq_low.into();
|
self.freq_low = freq_low.into();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
pub mod carrier;
|
pub mod carrier;
|
||||||
|
pub mod sample;
|
||||||
|
|
11
src/dsp_common/sample.rs
Normal file
11
src/dsp_common/sample.rs
Normal file
|
@ -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),
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
pub type PcmFrameMessage = Vec<i64>;
|
pub type PcmFrameMessage = Vec<crate::dsp_common::sample::PcmSample>;
|
||||||
pub type PcmSampleMessage = i64;
|
pub type PcmSampleMessage = i64;
|
||||||
pub type RawEthFrameMessage = Vec<u8>;
|
pub type RawEthFrameMessage = Vec<u8>;
|
||||||
|
|
Loading…
Reference in a new issue