Skip to main content

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}