Skip to main content

rustradio/
signal_source.rs

1//! Generate a pure signal.
2use crate::Result;
3
4use crate::block::{Block, BlockRet};
5use crate::stream::{ReadStream, WriteStream};
6use crate::{Complex, Float};
7
8/// Generate a pure complex sine wave.
9#[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
20/// Generate pure complex sine sine.
21impl SignalSourceComplex {
22    /// Create new `SignalSourceComplex` block.
23    #[must_use]
24    pub fn new(samp_rate: Float, freq: Float, amplitude: Float) -> (Self, ReadStream<Complex>) {
25        assert!(samp_rate > 0.0);
26        let (dst, dr) = crate::stream::new_stream();
27        (
28            Self {
29                dst,
30                current: 0.0,
31                amplitude,
32                rad_per_sample: 2.0 * std::f64::consts::PI * f64::from(freq) / f64::from(samp_rate),
33            },
34            dr,
35        )
36    }
37}
38
39impl Iterator for SignalSourceComplex {
40    type Item = Complex;
41    fn next(&mut self) -> Option<Complex> {
42        self.current = (self.current + self.rad_per_sample) % (2.0 * std::f64::consts::PI);
43        Some(
44            self.amplitude
45                * Complex::new(
46                    self.current.sin() as Float,
47                    (self.current - std::f64::consts::PI / 2.0).sin() as Float,
48                ),
49        )
50    }
51}
52
53impl Block for SignalSourceComplex {
54    fn work(&mut self) -> Result<BlockRet<'_>> {
55        let mut o = self.dst.write_buf()?;
56        let n = o.len();
57        for (to, from) in o.slice().iter_mut().zip(self.take(n)) {
58            *to = from;
59        }
60        o.produce(n, &[]);
61        Ok(BlockRet::WaitForStream(&self.dst, 1))
62    }
63}
64
65/// Generate a pure real sine wave.
66///
67/// TODO: not an efficient implementation, and duplicates code with the Complex
68/// version.
69#[derive(rustradio_macros::Block)]
70#[rustradio(crate)]
71pub struct SignalSourceFloat {
72    #[rustradio(out)]
73    dst: WriteStream<Float>,
74    amplitude: Float,
75    rad_per_sample: f64,
76    current: f64,
77}
78
79/// Generate pure complex sine sine.
80impl SignalSourceFloat {
81    /// Create new `SignalSourceFloat` block.
82    #[must_use]
83    pub fn new(samp_rate: Float, freq: Float, amplitude: Float) -> (Self, ReadStream<Float>) {
84        assert!(samp_rate > 0.0);
85        let (dst, dr) = crate::stream::new_stream();
86        (
87            Self {
88                dst,
89                current: 0.0,
90                amplitude,
91                rad_per_sample: 2.0 * std::f64::consts::PI * f64::from(freq) / f64::from(samp_rate),
92            },
93            dr,
94        )
95    }
96}
97
98impl Iterator for SignalSourceFloat {
99    type Item = Float;
100    fn next(&mut self) -> Option<Float> {
101        self.current = (self.current + self.rad_per_sample) % (2.0 * std::f64::consts::PI);
102        Some(self.amplitude * self.current.sin() as Float)
103    }
104}
105
106impl Block for SignalSourceFloat {
107    fn work(&mut self) -> Result<BlockRet<'_>> {
108        let mut o = self.dst.write_buf()?;
109        let n = o.len();
110        o.slice()
111            .iter_mut()
112            .zip(self.take(n))
113            .map(|(to, from)| {
114                *to = from;
115            })
116            .for_each(drop);
117        o.produce(n, &[]);
118        Ok(BlockRet::WaitForStream(&self.dst, 1))
119    }
120}
121/* vim: textwidth=80
122 */