pounder_test/dsp/src/lockin.rs

36 lines
1.0 KiB
Rust
Raw Normal View History

use super::{lowpass::Lowpass, Complex};
use generic_array::typenum::U3;
2021-01-21 21:55:33 +08:00
#[derive(Clone, Default)]
2021-01-21 21:55:33 +08:00
pub struct Lockin {
state: [Lowpass<U3>; 2],
2021-02-10 16:46:49 +08:00
k: u8,
2021-01-21 21:55:33 +08:00
}
impl Lockin {
2021-02-01 03:32:44 +08:00
/// Create a new Lockin with given IIR coefficients.
2021-02-10 16:46:49 +08:00
pub fn new(k: u8) -> Self {
let lp = Lowpass::default();
2021-02-01 19:37:44 +08:00
Self {
state: [lp.clone(), lp.clone()],
k,
2021-01-21 21:55:33 +08:00
}
}
2021-02-01 03:32:44 +08:00
/// Update the lockin with a sample taken at a given phase.
pub fn update(&mut self, sample: i32, phase: i32) -> Complex<i32> {
2021-01-21 21:55:33 +08:00
// Get the LO signal for demodulation.
2021-02-01 03:32:44 +08:00
let lo = Complex::from_angle(phase);
2021-01-21 21:55:33 +08:00
// Mix with the LO signal, filter with the IIR lowpass,
// return IQ (in-phase and quadrature) data.
// Note: 32x32 -> 64 bit multiplications are pretty much free.
Complex(
self.state[0]
.update(((sample as i64 * lo.0 as i64) >> 32) as _, self.k),
self.state[1]
.update(((sample as i64 * lo.1 as i64) >> 32) as _, self.k),
2021-01-21 21:55:33 +08:00
)
}
}