Skip to main content

plugin_host/
params.rs

1/// Valor de un parámetro — puede ser continuo o discreto.
2#[derive(Debug, Clone, Copy, PartialEq)]
3pub enum ParamValue {
4    /// Valor normalizado [0.0, 1.0]
5    Normalized(f64),
6    /// Valor en las unidades del plugin (Hz, dB, etc.)
7    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, // el caller debe normalizar
15        }
16    }
17}
18
19/// Descriptor de un parámetro del plugin.
20#[derive(Debug, Clone)]
21pub struct ParamDescriptor {
22    /// ID numérico del parámetro (estable entre sesiones)
23    pub id: u32,
24    pub name: String,
25    /// Unidades de display (ej. "Hz", "dB", "%")
26    pub unit: String,
27    pub min_value: f64,
28    pub max_value: f64,
29    pub default_value: f64,
30    /// Número de pasos discretos (0 = continuo)
31    pub step_count: u32,
32    /// Si true, el parámetro puede ser automatizado
33    pub automatable: bool,
34    /// Si true, es un bypass (booleano)
35    pub is_bypass: bool,
36    /// Módulo/grupo al que pertenece (para organizar en la UI)
37    pub module: String,
38}
39
40impl ParamDescriptor {
41    /// Convierte un valor plain al rango normalizado [0.0, 1.0].
42    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    /// Convierte un valor normalizado [0.0, 1.0] al rango plain.
50    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    /// Snap a step si el parámetro es discreto.
55    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/// Estado actual de todos los parámetros de un plugin.
63/// Se usa para serialización (presets) y para la UI.
64#[derive(Clone, Default)]
65pub struct ParamState {
66    /// Clave: param_id, Valor: valor normalizado
67    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}