rustradio/add_const.rs
1//! Add a constant value to every sample.
2use std::borrow::Cow;
3
4use crate::Sample;
5use crate::stream::{ReadStream, Tag, WriteStream};
6
7/// Add const value, implemented in terms of Map.
8///
9/// This is basically example code. We have `AddConst` and `add_const` doing the
10/// same thing.
11#[allow(clippy::type_complexity)]
12#[must_use]
13pub fn add_const<T>(
14 src: ReadStream<T>,
15 val: T,
16) -> (
17 crate::convert::Map<T, T, impl for<'a> Fn(T, &'a [Tag]) -> (T, Cow<'a, [Tag]>)>,
18 ReadStream<T>,
19)
20where
21 T: Sample + std::ops::Add<Output = T>,
22{
23 crate::convert::Map::keep_tags(src, "add_const", move |x| x + val)
24}
25
26/// `AddConst` adds a constant value to every sample.
27///
28/// Tags are preserved.
29///
30/// ```
31/// use rustradio::graph::{Graph, GraphRunner};
32/// use rustradio::blocks::{ConstantSource, SignalSourceFloat, AddConst, NullSink};
33///
34/// let mut graph = Graph::new();
35///
36/// // Add a constant value. Could just as well use AddConst instead of Add.
37/// let (src, src_out) = SignalSourceFloat::new(44100.0, 1000.0, 1.0);
38///
39/// // Sum up the streams.
40/// let (sum, sum_out) = AddConst::new(src_out, 1.0);
41///
42/// graph.add(Box::new(src));
43/// graph.add(Box::new(sum));
44///
45/// // Set up dummy sink.
46/// let sink = NullSink::new(sum_out);
47/// # return Ok(());
48/// graph.run()?;
49/// # Ok::<(), anyhow::Error>(())
50/// ```
51#[derive(rustradio_macros::Block)]
52#[rustradio(crate, new, sync)]
53pub struct AddConst<T: Sample + std::ops::Add<Output = T>> {
54 val: T,
55 #[rustradio(in)]
56 src: ReadStream<T>,
57 #[rustradio(out)]
58 dst: WriteStream<T>,
59}
60
61impl<T> AddConst<T>
62where
63 T: Sample + std::ops::Add<Output = T>,
64{
65 #[must_use]
66 fn process_sync(&self, a: T) -> T {
67 a + self.val
68 }
69}