Skip to main content

sim_lib_view_daw/
synth.rs

1//! The synth and signal lenses: parameter panels, modulation matrix, waveform,
2//! and spectrum.
3//!
4//! A synth patch is a parameter map (name -> value). The panel renders each
5//! parameter as a `scene/knob`, plus a modulation matrix (`scene/matrix`) and
6//! live signal displays (`scene/waveform`, `scene/spectrum`). Parameter changes
7//! flow through `intent/set-param` (see `param`).
8
9use sim_kernel::Expr;
10use sim_lib_scene::{node, sym};
11
12/// The synth panel lens id.
13pub const SYNTH_LENS: &str = "view:daw-synth";
14
15/// Render a synth parameter map as a knob panel plus a modulation matrix.
16pub fn synth_panel(params: &Expr) -> Expr {
17    let knobs = match params {
18        Expr::Map(entries) => entries
19            .iter()
20            .map(|(key, value)| knob(key, value))
21            .collect(),
22        _ => Vec::new(),
23    };
24    node(
25        "stack",
26        vec![
27            ("role", sym("synth")),
28            ("dir", sym("column")),
29            (
30                "children",
31                Expr::List(vec![
32                    node(
33                        "stack",
34                        vec![
35                            ("role", sym("knobs")),
36                            ("dir", sym("row")),
37                            ("children", Expr::List(knobs)),
38                        ],
39                    ),
40                    modulation_matrix(&[vec![0.0, 0.0], vec![0.0, 0.0]]),
41                ]),
42            ),
43        ],
44    )
45}
46
47fn knob(name: &Expr, value: &Expr) -> Expr {
48    node(
49        "knob",
50        vec![
51            ("param", name.clone()),
52            ("min", number(0.0)),
53            ("max", number(1.0)),
54            ("value", value.clone()),
55        ],
56    )
57}
58
59/// A modulation matrix as an editable `scene/matrix`.
60pub fn modulation_matrix(rows: &[Vec<f64>]) -> Expr {
61    let rows = rows
62        .iter()
63        .map(|row| Expr::List(row.iter().map(|v| number(*v)).collect()))
64        .collect();
65    node(
66        "matrix",
67        vec![
68            ("role", sym("modulation")),
69            ("rows", Expr::List(rows)),
70            ("editable", Expr::Bool(true)),
71        ],
72    )
73}
74
75/// A sampled-signal display.
76pub fn waveform_view(samples: &[f32]) -> Expr {
77    node(
78        "waveform",
79        vec![(
80            "samples",
81            Expr::List(samples.iter().map(|s| number(*s as f64)).collect()),
82        )],
83    )
84}
85
86/// A frequency-domain display.
87pub fn spectrum_view(bins: &[f32]) -> Expr {
88    node(
89        "spectrum",
90        vec![(
91            "bins",
92            Expr::List(bins.iter().map(|b| number(*b as f64)).collect()),
93        )],
94    )
95}
96
97use sim_value::build::float as number;