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    Crop {
53        x: Box<NodeRenderer>,
54        a: f64,
55        b: f64,
56    },
57    Join(Vec<NodeRenderer>),
58    Channel {
59        x: Box<NodeRenderer>,
60        k: usize,
61    },
62    Filter {
63        site: SiteId,
64        x: Box<NodeRenderer>,
65        cutoff: Box<NodeRenderer>,
66        q: Box<NodeRenderer>,
67        gain: Box<NodeRenderer>,
68    },
69    Physics {
70        site: SiteId,
71    },
72}
73
74#[derive(Clone, Debug, PartialEq)]
75pub enum Site {
76    Filter(Shape),
77    Physics(Box<Params>),
78}
79
80impl From<sva_formula::Unary> for Unary {
81    fn from(written: sva_formula::Unary) -> Unary {
82        match written {
83            sva_formula::Unary::Sin => Unary::Sin,
84            sva_formula::Unary::Cos => Unary::Cos,
85            sva_formula::Unary::Exp => Unary::Exp,
86            sva_formula::Unary::Sqrt => Unary::Sqrt,
87            sva_formula::Unary::Abs => Unary::Abs,
88            sva_formula::Unary::Tanh => Unary::Tanh,
89            sva_formula::Unary::Log => Unary::Log,
90            sva_formula::Unary::Sat => Unary::Sat,
91        }
92    }
93}
94
95impl Unary {
96    pub fn apply(self, x: f64) -> f64 {
97        match self {
98            Unary::Sin => x.sin(),
99            Unary::Cos => x.cos(),
100            Unary::Exp => x.exp(),
101            Unary::Sqrt => x.sqrt(),
102            Unary::Abs => x.abs(),
103            Unary::Tanh => x.tanh(),
104            Unary::Log => x.ln(),
105            Unary::Sat => x.clamp(-1.0, 1.0),
106        }
107    }
108}
109
110impl Binary {
111    pub fn apply(self, a: f64, b: f64) -> f64 {
112        match self {
113            Binary::Max => a.max(b),
114            Binary::Min => a.min(b),
115            Binary::Mod => a.rem_euclid(b),
116        }
117    }
118}