unwrap: clean up docs and names

This commit is contained in:
Robert Jördens 2020-12-05 12:41:02 +01:00
parent 526fea8e23
commit 974fa6e220
1 changed files with 22 additions and 19 deletions

View File

@ -1,24 +1,25 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Get phase wrap from x to y. /// Subtract `y - x` with signed overflow.
/// ///
/// Phases are modulo integer overflow. The wraps have the same bias as /// This is very similar to `i32::overflowing_sub(y, x)` except that the
/// the base data type itself. /// overflow indicator is not a boolean but the signum of the overflow.
/// /// Additionally it's typically faster.
/// Args:
/// * `x`: Old phase sample
/// * `y`: New phase sample
/// ///
/// Returns: /// Returns:
/// A tuple containg the (wrapped) phase difference and the signum of the wrap. /// A tuple containg the (wrapped) difference `y - x` and the signum of the
/// overflow.
#[inline(always)] #[inline(always)]
pub fn get_wrap(x: i32, y: i32) -> (i32, i8) { pub fn overflowing_sub(y: i32, x: i32) -> (i32, i8) {
let delta = y.wrapping_sub(x); let delta = y.wrapping_sub(x);
let wrap = (delta >= 0) as i8 - (y >= x) as i8; let wrap = (delta >= 0) as i8 - (y >= x) as i8;
(delta, wrap) (delta, wrap)
} }
/// Phase unwrapper. /// Overflow unwrapper.
///
/// This is unwrapping as in the phase unwrapping context, not unwrapping as
/// in the `Result`/`Option` context.
#[derive(Copy, Clone, Default, Deserialize, Serialize)] #[derive(Copy, Clone, Default, Deserialize, Serialize)]
pub struct Unwrapper { pub struct Unwrapper {
// last input // last input
@ -28,19 +29,18 @@ pub struct Unwrapper {
} }
impl Unwrapper { impl Unwrapper {
/// Unwrap a new sample from a phase sequence and update the unwrapper /// Unwrap a new sample from a sequence and update the unwrapper state.
/// state.
/// ///
/// Args: /// Args:
/// * `x`: New phase sample /// * `x`: New sample
/// ///
/// Returns: /// Returns:
/// A tuple containing the (wrapped) phase difference and the signed /// A tuple containing the (wrapped) difference `x - x_old` and the signed
/// number of phase wraps accumulated to the new sample. /// number of wraps accumulated by `x`.
pub fn update(&mut self, x: i32) -> (i32, i32) { pub fn update(&mut self, x: i32) -> (i32, i32) {
let (dx, v) = get_wrap(self.x, x); let (dx, v) = overflowing_sub(x, self.x);
self.x = x; self.x = x;
self.v = self.v.wrapping_add(v as i32); self.v = self.v.saturating_add(v as i32);
(dx, self.v) (dx, self.v)
} }
} }
@ -73,8 +73,11 @@ mod tests {
] ]
.iter() .iter()
{ {
let (_dx, w) = get_wrap(*x0, *x1); let (dx, w) = overflowing_sub(*x1, *x0);
assert_eq!(*v, w, " = get_wrap({:#x}, {:#x})", *x0, *x1); assert_eq!(*v, w, " = overflowing_sub({:#x}, {:#x})", *x0, *x1);
let (dx0, w0) = x1.overflowing_sub(*x0);
assert_eq!(w0, w != 0);
assert_eq!(dx, dx0);
} }
} }
} }