firewheel_core/param/
range.rs1#[cfg(not(feature = "std"))]
2use num_traits::Float;
3
4#[derive(Debug, Clone, Copy, PartialEq)]
6pub struct LinearRange {
7 pub min: f32,
8 pub max: f32,
9}
10
11impl LinearRange {
12 pub fn new(min: f32, max: f32) -> Self {
13 Self { min, max }
14 }
15
16 pub fn clamp(&self, val: f32) -> f32 {
18 if self.min > self.max {
19 val.min(self.min).max(self.max)
20 } else {
21 val.min(self.max).max(self.min)
22 }
23 }
24}
25
26impl Default for LinearRange {
27 fn default() -> Self {
28 Self { min: 0.0, max: 1.0 }
29 }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq)]
35pub struct NormToFreqRange {
36 min_hz: f32,
37 max_hz: f32,
38
39 min_log2: f32,
40 range: f32,
41}
42
43impl NormToFreqRange {
44 pub fn new(min_hz: f32, max_hz: f32) -> Self {
45 assert!(min_hz < max_hz);
46 assert_ne!(min_hz, 0.0);
47 assert_ne!(max_hz, 0.0);
48
49 let min_log2 = min_hz.log2();
50 let range = max_hz.log2() - min_log2;
51
52 Self {
53 min_hz,
54 max_hz,
55 min_log2,
56 range,
57 }
58 }
59
60 pub fn min_hz(&self) -> f32 {
61 self.min_hz
62 }
63
64 pub fn max_hz(&self) -> f32 {
65 self.max_hz
66 }
67
68 pub fn to_hz(&self, normalized: f32) -> f32 {
71 if normalized <= 0.0 {
72 return self.min_hz;
73 }
74
75 if normalized >= 1.0 {
76 return self.max_hz;
77 }
78
79 2.0f32.powf((normalized * self.range) + self.min_log2)
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq)]
86pub struct NormToPowRange {
87 pub exponent: f32,
88 min: f32,
89 max: f32,
90}
91
92impl NormToPowRange {
93 pub fn new(min: f32, max: f32, exponent: f32) -> Self {
94 assert!(min <= max);
95
96 Self { exponent, min, max }
97 }
98
99 pub fn min(&self) -> f32 {
100 self.min
101 }
102
103 pub fn max(&self) -> f32 {
104 self.max
105 }
106
107 pub fn to_dsp(&self, normalized: f32) -> f32 {
110 if normalized <= 0.0 {
111 return self.min;
112 }
113
114 if normalized >= 1.0 {
115 return self.max;
116 }
117
118 normalized.powf(self.exponent) * (self.max - self.min) + self.min
119 }
120}