orion_sdr/modulate/
bpsk.rs1use crate::core::{Block, WorkReport};
6use crate::dsp::Rotator;
7use num_complex::Complex32 as C32;
8
9#[derive(Debug, Clone, Copy, Default)]
12pub struct BpskMapper;
13
14impl BpskMapper {
15 pub fn new() -> Self {
16 Self
17 }
18}
19
20impl Block for BpskMapper {
21 type In = u8;
22 type Out = C32;
23
24 #[inline(always)]
25 fn process(&mut self, input: &[u8], output: &mut [C32]) -> WorkReport {
26 let n = input.len().min(output.len());
27 let mut i = 0;
28 let nn = n & !3;
29 while i < nn {
30 output[i] = C32::new(if (input[i] & 1) == 0 { 1.0 } else { -1.0 }, 0.0);
31 output[i + 1] = C32::new(if (input[i + 1] & 1) == 0 { 1.0 } else { -1.0 }, 0.0);
32 output[i + 2] = C32::new(if (input[i + 2] & 1) == 0 { 1.0 } else { -1.0 }, 0.0);
33 output[i + 3] = C32::new(if (input[i + 3] & 1) == 0 { 1.0 } else { -1.0 }, 0.0);
34 i += 4;
35 }
36 while i < n {
37 output[i] = C32::new(if (input[i] & 1) == 0 { 1.0 } else { -1.0 }, 0.0);
38 i += 1;
39 }
40 WorkReport {
41 in_read: n,
42 out_written: n,
43 }
44 }
45}
46
47#[derive(Debug, Clone)]
51pub struct BpskMod {
52 gain: f32,
53 rot: Rotator,
54}
55
56impl BpskMod {
57 pub fn new(fs: f32, rf_hz: f32, gain: f32) -> Self {
58 Self {
59 gain,
60 rot: Rotator::new(rf_hz, fs),
61 }
62 }
63 pub fn set_gain(&mut self, g: f32) {
64 self.gain = g;
65 }
66}
67
68impl Block for BpskMod {
69 type In = C32;
70 type Out = C32;
71
72 #[inline(always)]
73 fn process(&mut self, input: &[C32], output: &mut [C32]) -> WorkReport {
74 let n = input.len().min(output.len());
75 let g = self.gain;
76 let mut i = 0;
77 let nn = n & !3;
78 while i < nn {
79 let s0 = input[i];
80 let r0 = self.rot.next();
81 let s1 = input[i + 1];
82 let r1 = self.rot.next();
83 let s2 = input[i + 2];
84 let r2 = self.rot.next();
85 let s3 = input[i + 3];
86 let r3 = self.rot.next();
87 output[i] = C32::new(
88 g * s0.re.mul_add(r0.re, -s0.im * r0.im),
89 g * s0.im.mul_add(r0.re, s0.re * r0.im),
90 );
91 output[i + 1] = C32::new(
92 g * s1.re.mul_add(r1.re, -s1.im * r1.im),
93 g * s1.im.mul_add(r1.re, s1.re * r1.im),
94 );
95 output[i + 2] = C32::new(
96 g * s2.re.mul_add(r2.re, -s2.im * r2.im),
97 g * s2.im.mul_add(r2.re, s2.re * r2.im),
98 );
99 output[i + 3] = C32::new(
100 g * s3.re.mul_add(r3.re, -s3.im * r3.im),
101 g * s3.im.mul_add(r3.re, s3.re * r3.im),
102 );
103 i += 4;
104 }
105 while i < n {
106 let s = input[i];
107 let r = self.rot.next();
108 output[i] = C32::new(
109 g * s.re.mul_add(r.re, -s.im * r.im),
110 g * s.im.mul_add(r.re, s.re * r.im),
111 );
112 i += 1;
113 }
114 WorkReport {
115 in_read: n,
116 out_written: n,
117 }
118 }
119}