rustradio/
signal_source.rs1use crate::Result;
3
4use crate::block::{Block, BlockRet};
5use crate::stream::{ReadStream, WriteStream};
6use crate::{Complex, Float};
7
8#[derive(rustradio_macros::Block)]
10#[rustradio(crate)]
11pub struct SignalSourceComplex {
12 #[rustradio(out)]
13 dst: WriteStream<Complex>,
14
15 amplitude: Float,
16 rad_per_sample: f64,
17 current: f64,
18}
19
20impl SignalSourceComplex {
22 #[must_use]
24 pub fn new(samp_rate: Float, freq: Float, amplitude: Float) -> (Self, ReadStream<Complex>) {
25 let (dst, dr) = crate::stream::new_stream();
26 (
27 Self {
28 dst,
29 current: 0.0,
30 amplitude,
31 rad_per_sample: 2.0 * std::f64::consts::PI * f64::from(freq) / f64::from(samp_rate),
32 },
33 dr,
34 )
35 }
36}
37
38impl Iterator for SignalSourceComplex {
39 type Item = Complex;
40 fn next(&mut self) -> Option<Complex> {
41 self.current = (self.current + self.rad_per_sample) % (2.0 * std::f64::consts::PI);
42 Some(
43 self.amplitude
44 * Complex::new(
45 self.current.sin() as Float,
46 (self.current - std::f64::consts::PI / 2.0).sin() as Float,
47 ),
48 )
49 }
50}
51
52impl Block for SignalSourceComplex {
53 fn work(&mut self) -> Result<BlockRet<'_>> {
54 let mut o = self.dst.write_buf()?;
55 let n = o.len();
56 for (to, from) in o.slice().iter_mut().zip(self.take(n)) {
57 *to = from;
58 }
59 o.produce(n, &[]);
60 Ok(BlockRet::Again)
61 }
62}
63
64#[derive(rustradio_macros::Block)]
69#[rustradio(crate)]
70pub struct SignalSourceFloat {
71 #[rustradio(out)]
72 dst: WriteStream<Float>,
73 amplitude: Float,
74 rad_per_sample: f64,
75 current: f64,
76}
77
78impl SignalSourceFloat {
80 #[must_use]
82 pub fn new(samp_rate: Float, freq: Float, amplitude: Float) -> (Self, ReadStream<Float>) {
83 let (dst, dr) = crate::stream::new_stream();
84 (
85 Self {
86 dst,
87 current: 0.0,
88 amplitude,
89 rad_per_sample: 2.0 * std::f64::consts::PI * f64::from(freq) / f64::from(samp_rate),
90 },
91 dr,
92 )
93 }
94}
95
96impl Iterator for SignalSourceFloat {
97 type Item = Float;
98 fn next(&mut self) -> Option<Float> {
99 self.current = (self.current + self.rad_per_sample) % (2.0 * std::f64::consts::PI);
100 Some(self.amplitude * self.current.sin() as Float)
101 }
102}
103
104impl Block for SignalSourceFloat {
105 fn work(&mut self) -> Result<BlockRet<'_>> {
106 let mut o = self.dst.write_buf()?;
107 let n = o.len();
108 o.slice()
109 .iter_mut()
110 .zip(self)
111 .map(|(to, from)| {
112 *to = from;
113 })
114 .for_each(drop);
115 o.produce(n, &[]);
116 Ok(BlockRet::Again)
117 }
118}
119