music_math/
binaryops.rs

1use num_traits::Float;
2
3/// Clip two values within a range
4pub fn clip<T: PartialOrd>(value: T, min: T, max: T) -> T {
5    if value < min {
6        min
7    } else if value > max {
8        max
9    } else {
10        value
11    }
12}
13
14/// Wrap a value within a range
15pub fn wrap<T: Float>(value: T, min: T, max: T) -> T {
16    let range = max.sub(min);
17    if value < min {
18        // max - (min - value) % range
19        max.sub(min.sub(value)).rem(range)
20    } else if value > max {
21        min.add(value.sub(max).rem(range))
22    } else {
23        value
24    }
25}
26
27/// Fold a value within a range
28/// # Panics
29/// If a type conversion fails.
30pub fn fold<T: Float>(value: T, min: T, max: T) -> T {
31    let range = max.sub(min);
32    let two = T::from(2.0).expect("Could not convert 2.0 to T");
33    let r = range.mul(two);
34    let value = (value.sub(min).rem(r)).abs();
35
36    // Compute return value
37    min.add(if value > range { r.sub(value) } else { value })
38}