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        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/// Generate a pure real sine wave.
65///
66/// TODO: not an efficient implementation, and duplicates code with the Complex
67/// version.
68#[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
78/// Generate pure complex sine sine.
79impl SignalSourceFloat {
80    /// Create new `SignalSourceFloat` block.
81    #[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/* vim: textwidth=80
120 */