1use crate::core::{Block, WorkReport};
5use crate::dsp::{Nco, mix_with_nco};
6use num_complex::Complex32 as C32;
7
8#[derive(Debug, Clone)]
10pub struct PmDirectPhaseMod {
11 kp_rad_per_unit: f32,
12 rf_nco: Nco,
13 gain: f32,
14}
15
16impl PmDirectPhaseMod {
17 pub fn new(sample_rate: f32, kp_rad_per_unit: f32, rf_hz: f32) -> Self {
18 Self {
19 kp_rad_per_unit,
20 rf_nco: Nco::new(rf_hz, sample_rate),
21 gain: 1.0,
22 }
23 }
24 pub fn set_gain(&mut self, g: f32) {
25 self.gain = g;
26 }
27 pub fn set_sensitivity(&mut self, kp_rad_per_unit: f32) {
28 self.kp_rad_per_unit = kp_rad_per_unit;
29 }
30}
31
32impl Block for PmDirectPhaseMod {
33 type In = f32;
34 type Out = C32;
35
36 fn process(&mut self, input: &[f32], output: &mut [C32]) -> WorkReport {
37 let n = input.len().min(output.len());
38 for i in 0..n {
39 let phi = self.kp_rad_per_unit * input[i];
40 let base = C32::new(phi.cos(), phi.sin()) * self.gain;
41 output[i] = mix_with_nco(base, &mut self.rf_nco);
42 }
43 WorkReport {
44 in_read: n,
45 out_written: n,
46 }
47 }
48}