normal_map/f32/mod.rs
1//! Normal mapping using `f32` as the internal unit.
2
3mod discrete;
4mod linear;
5mod linear_base;
6mod log2;
7mod power;
8
9pub use discrete::DiscreteMap;
10pub use linear::LinearMap;
11pub use log2::Log2Map;
12pub use power::PowerMap;
13
14/// The type of mapping to use
15#[derive(Debug)]
16pub enum Mapper {
17 /// Linear mapping
18 ///
19 /// Please note if you use `Unit::Decibels`, then the decibels
20 /// will be linearly mapped, not the raw amplitude.
21 Lin(LinearMap),
22 /// Exponential mapping where the normalized value is raised to the
23 /// supplied exponent.
24 ///
25 /// Please note if you use `Unit::Decibels`, then the decibels
26 /// will be linearly mapped, not the raw amplitude.
27 Pow(PowerMap),
28 /// Logarithmic mapping using `log2`. This is useful for frequency (Hz) values.
29 Log2(Log2Map),
30 /// Discrete `isize` integer mapping
31 ///
32 /// A supplied enum may be used as well as long
33 /// as it implements `From<isize> + Into<isize> + Copy + Clone`.
34 Discrete(DiscreteMap),
35}
36
37#[derive(Debug)]
38/// The unit to use
39pub enum Unit {
40 /// Generic units
41 Generic,
42 /// Decibel units.
43 ///
44 /// Please note that values in and out of the mapper are raw amplitudes, not decibels.
45 ///
46 /// * `neg_infinity_clamp`: The point at which any values less than
47 /// or equal to this value (e.g. `Some(-90.0)` for -90 dB) are clampled to negative
48 /// infinity (silence). Set this to `None` for no clamping.
49 Decibels { neg_infinity_clamp: Option<f32> },
50}
51
52/// A mapper than maps a range of values to and from the normalized
53/// `f32` range `[0.0, 1.0]`.
54#[derive(Debug)]
55pub struct NormalMap {
56 /// The current mapper in use
57 pub mapper: Mapper,
58}
59
60impl NormalMap {
61 /// Create a new `NormalMap` with linear mapping.
62 ///
63 /// Please note if you use `Unit::Decibels`, then the decibels
64 /// are what will be linearly mapped, not the raw amplitude.
65 ///
66 /// # Arguments
67 ///
68 /// * min - the minimum of the range
69 /// * max - the maximum of the range
70 /// * unit - the type of unit
71 pub fn linear(min: f32, max: f32, unit: Unit) -> Self {
72 Self {
73 mapper: Mapper::Lin(LinearMap::new(min, max, unit)),
74 }
75 }
76
77 /// Create a new `NormalMap` with an exponential mapping where the
78 /// normalized value is raised to the supplied exponent.
79 ///
80 /// Please note if you use `Unit::Decibels`, then the decibels
81 /// are what will be mapped, not the raw amplitude.
82 ///
83 /// # Arguments
84 ///
85 /// * min - the minimum of the range
86 /// * max - the maximum of the range
87 /// * exponent - the exponent to raise the normalized value to
88 /// * unit - the type of unit
89 ///
90 /// # Panics
91 ///
92 /// * Panics when `exponent = 0.0`.
93 pub fn power(min: f32, max: f32, exponent: f32, unit: Unit) -> Self {
94 Self {
95 mapper: Mapper::Pow(PowerMap::new(min, max, exponent, unit)),
96 }
97 }
98
99 /// Create a new `NormalMap` with a logarithmic mapping using `log2`.
100 /// This is useful for frequency (Hz) values.
101 ///
102 /// # Arguments
103 ///
104 /// * min - the minimum of the range, must be > 0.0
105 /// * max - the maximum of the range, must be > 0.0
106 ///
107 /// # Panics
108 ///
109 /// * Panics when either `min` or `max` <= 0.0.
110 pub fn log2(min: f32, max: f32) -> Self {
111 Self {
112 mapper: Mapper::Log2(Log2Map::new(min, max)),
113 }
114 }
115
116 /// Create a new `NormalMap` with a discrete `isize` integer range.
117 ///
118 /// A supplied enum may be used as well as long
119 /// as it implements `From<isize> + Into<isize> + Copy + Clone`.
120 ///
121 /// # Arguments
122 ///
123 /// * min - the minimum of the range
124 /// * max - the maximum of the range
125 pub fn discrete<T>(min: T, max: T) -> Self
126 where
127 T: From<isize> + Into<isize> + Copy + Clone,
128 {
129 Self {
130 mapper: Mapper::Discrete(DiscreteMap::new(min, max)),
131 }
132 }
133
134 /// Map an `f32` value to the normalized range `[0.0, 1.0]`.
135 pub fn normalize(&self, value: f32) -> f32 {
136 match &self.mapper {
137 Mapper::Lin(mapper) => mapper.normalize(value),
138 Mapper::Pow(mapper) => mapper.normalize(value),
139 Mapper::Log2(mapper) => mapper.normalize(value),
140 Mapper::Discrete(mapper) => mapper.normalize_float(value),
141 }
142 }
143
144 /// Map an array of `f32` values to the normalized range `[0.0, 1.0]`.
145 ///
146 /// Values will be processed up to the length of the shortest array.
147 pub fn normalize_array(&self, in_values: &[f32], out_normalized: &mut [f32]) {
148 match &self.mapper {
149 Mapper::Lin(mapper) => mapper.normalize_array(in_values, out_normalized),
150 Mapper::Pow(mapper) => mapper.normalize_array(in_values, out_normalized),
151 Mapper::Log2(mapper) => mapper.normalize_array(in_values, out_normalized),
152 Mapper::Discrete(mapper) => mapper.normalize_array_float(in_values, out_normalized),
153 }
154 }
155
156 /// Un-map a normalized value to the corresponding `f32` value.
157 pub fn denormalize(&self, normalized: f32) -> f32 {
158 match &self.mapper {
159 Mapper::Lin(mapper) => mapper.denormalize(normalized),
160 Mapper::Pow(mapper) => mapper.denormalize(normalized),
161 Mapper::Log2(mapper) => mapper.denormalize(normalized),
162 Mapper::Discrete(mapper) => mapper.denormalize_float(normalized),
163 }
164 }
165
166 /// Un-map an array of normalized values to the corresponding `f32` value.
167 ///
168 /// Values will be processed up to the length of the shortest array.
169 pub fn denormalize_array(&self, in_normalized: &[f32], out_values: &mut [f32]) {
170 match &self.mapper {
171 Mapper::Lin(mapper) => mapper.denormalize_array(in_normalized, out_values),
172 Mapper::Pow(mapper) => mapper.denormalize_array(in_normalized, out_values),
173 Mapper::Log2(mapper) => mapper.denormalize_array(in_normalized, out_values),
174 Mapper::Discrete(mapper) => mapper.denormalize_array_float(in_normalized, out_values),
175 }
176 }
177}