1#[derive(Debug, Clone, Copy, PartialEq)]
3pub enum ParamValue {
4 Normalized(f64),
6 Plain(f64),
8}
9
10impl ParamValue {
11 pub fn normalized(self) -> f64 {
12 match self {
13 ParamValue::Normalized(v) => v.clamp(0.0, 1.0),
14 ParamValue::Plain(v) => v, }
16 }
17}
18
19#[derive(Debug, Clone)]
21pub struct ParamDescriptor {
22 pub id: u32,
24 pub name: String,
25 pub unit: String,
27 pub min_value: f64,
28 pub max_value: f64,
29 pub default_value: f64,
30 pub step_count: u32,
32 pub automatable: bool,
34 pub is_bypass: bool,
36 pub module: String,
38}
39
40impl ParamDescriptor {
41 pub fn normalize(&self, plain: f64) -> f64 {
43 if (self.max_value - self.min_value).abs() < f64::EPSILON {
44 return 0.0;
45 }
46 ((plain - self.min_value) / (self.max_value - self.min_value)).clamp(0.0, 1.0)
47 }
48
49 pub fn denormalize(&self, normalized: f64) -> f64 {
51 self.min_value + normalized.clamp(0.0, 1.0) * (self.max_value - self.min_value)
52 }
53
54 pub fn snap(&self, normalized: f64) -> f64 {
56 if self.step_count == 0 { return normalized; }
57 let steps = self.step_count as f64;
58 (normalized * steps).round() / steps
59 }
60}
61
62#[derive(Clone, Default)]
65pub struct ParamState {
66 values: std::collections::HashMap<u32, f64>,
68}
69
70impl ParamState {
71 pub fn set(&mut self, id: u32, value: f64) {
72 self.values.insert(id, value.clamp(0.0, 1.0));
73 }
74
75 pub fn get(&self, id: u32) -> Option<f64> {
76 self.values.get(&id).copied()
77 }
78
79 pub fn iter(&self) -> impl Iterator<Item = (u32, f64)> + '_ {
80 self.values.iter().map(|(&k, &v)| (k, v))
81 }
82
83 pub fn len(&self) -> usize {
84 self.values.len()
85 }
86
87 pub fn is_empty(&self) -> bool {
88 self.values.is_empty()
89 }
90}