Skip to main content

sva_samples/machine/
renderer.rs

1// Concern: the node renderer sva-engine hands this crate | Non-concern: building it (sva-engine lower.rs), running it (mod.rs, ops.rs) | IO: none
2
3use sva_formula::Shape;
4
5use crate::physics::Params;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
8pub struct BufId(pub u32);
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct SiteId(pub u32);
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum Unary {
15    Sin,
16    Cos,
17    Exp,
18    Sqrt,
19    Abs,
20    Tanh,
21    Log,
22    Sat,
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub enum Binary {
27    Max,
28    Min,
29    Mod,
30}
31
32/// Every closed form-typed subterm was collapsed to a `Buffer` before this tree was built, so there
33/// is no oscillator, no series, no delta and no rate here: `rand` arrives folded.
34#[derive(Clone, Debug, PartialEq)]
35pub enum NodeRenderer {
36    Const(f64),
37    Time,
38    Buffer {
39        id: BufId,
40        shift: i64,
41    },
42    SelfAt {
43        steps: u32,
44    },
45    Add(Vec<NodeRenderer>),
46    Mul(Vec<NodeRenderer>),
47    Sub(Box<NodeRenderer>, Box<NodeRenderer>),
48    Div(Box<NodeRenderer>, Box<NodeRenderer>),
49    Pow(Box<NodeRenderer>, Box<NodeRenderer>),
50    Map(Unary, Box<NodeRenderer>),
51    Zip(Binary, Box<NodeRenderer>, Box<NodeRenderer>),
52    /// `x` over the window `[a, b)` with a raised-cosine `rise` and `fall` inside it.
53    Crop {
54        x: Box<NodeRenderer>,
55        a: f64,
56        b: f64,
57        rise: f64,
58        fall: f64,
59    },
60    Join(Vec<NodeRenderer>),
61    Channel {
62        x: Box<NodeRenderer>,
63        k: usize,
64    },
65    Filter {
66        site: SiteId,
67        x: Box<NodeRenderer>,
68        cutoff: Box<NodeRenderer>,
69        q: Box<NodeRenderer>,
70        gain: Box<NodeRenderer>,
71    },
72    Physics {
73        site: SiteId,
74    },
75}
76
77#[derive(Clone, Debug, PartialEq)]
78pub enum Site {
79    Filter(Shape),
80    Physics(Box<Params>),
81}
82
83impl From<sva_formula::Unary> for Unary {
84    fn from(written: sva_formula::Unary) -> Unary {
85        match written {
86            sva_formula::Unary::Sin => Unary::Sin,
87            sva_formula::Unary::Cos => Unary::Cos,
88            sva_formula::Unary::Exp => Unary::Exp,
89            sva_formula::Unary::Sqrt => Unary::Sqrt,
90            sva_formula::Unary::Abs => Unary::Abs,
91            sva_formula::Unary::Tanh => Unary::Tanh,
92            sva_formula::Unary::Log => Unary::Log,
93            sva_formula::Unary::Sat => Unary::Sat,
94        }
95    }
96}
97
98impl Unary {
99    pub fn apply(self, x: f64) -> f64 {
100        match self {
101            Unary::Sin => x.sin(),
102            Unary::Cos => x.cos(),
103            Unary::Exp => x.exp(),
104            Unary::Sqrt => x.sqrt(),
105            Unary::Abs => x.abs(),
106            Unary::Tanh => x.tanh(),
107            Unary::Log => x.ln(),
108            Unary::Sat => x.clamp(-1.0, 1.0),
109        }
110    }
111}
112
113impl Binary {
114    pub fn apply(self, a: f64, b: f64) -> f64 {
115        match self {
116            Binary::Max => a.max(b),
117            Binary::Min => a.min(b),
118            Binary::Mod => a.rem_euclid(b),
119        }
120    }
121}