Skip to content

Commit

Permalink
make unwrapper generic
Browse files Browse the repository at this point in the history
  • Loading branch information
jordens committed Oct 24, 2023
1 parent 634e03a commit fa5c2d4
Showing 1 changed file with 39 additions and 13 deletions.
52 changes: 39 additions & 13 deletions src/unwrap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
use core::cmp::PartialOrd;
use num_traits::{identities::Zero, ops::wrapping::WrappingSub};
use core::{
cmp::PartialOrd,
ops::{BitAnd, Shr},
};
use num_traits::{
cast::AsPrimitive,
identities::Zero,
ops::wrapping::{WrappingAdd, WrappingSub},
Signed,
};
use serde::{Deserialize, Serialize};

/// Subtract `y - x` with signed overflow.
Expand Down Expand Up @@ -47,37 +55,55 @@ pub fn saturating_scale(lo: i32, hi: i32, shift: u32) -> i32 {
/// This is unwrapping as in the phase and overflow unwrapping context, not
/// unwrapping as in the `Result`/`Option` context.
#[derive(Copy, Clone, Default, Deserialize, Serialize)]
pub struct Unwrapper {
pub struct Unwrapper<Q> {
/// current output
y: i64,
y: Q,
}

impl Unwrapper {
impl<Q> Unwrapper<Q>
where
Q: 'static + WrappingAdd + Copy,
{
/// Feed a new sample..
///
/// Args:
/// * `x`: New sample
///
/// Returns:
/// The (wrapped) difference `x - x_old`
pub fn update(&mut self, x: i32) -> i32 {
let dx = x.wrapping_sub(self.y as _);
self.y = self.y.wrapping_add(dx as _);
pub fn update<P>(&mut self, x: P) -> P
where
P: 'static + WrappingSub + Copy + AsPrimitive<Q>,
Q: AsPrimitive<P>,
{
let dx = x.wrapping_sub(&self.y.as_());
self.y = self.y.wrapping_add(&dx.as_());
dx
}

/// The current number of wraps
pub fn wraps(&self) -> i32 {
((self.y >> 32) as i32).wrapping_add(((self.y >> 31) & 1) as _)
pub fn wraps<P, const S: u32>(&self) -> P
where
Q: AsPrimitive<P> + Shr<u32, Output = Q>,
bool: AsPrimitive<P>,
P: 'static + Copy + WrappingAdd + Signed + BitAnd<i32, Output = P>,
{
(self.y >> S)
.as_()
.wrapping_add(&((self.y >> (S - 1)).as_() & 1))
}

/// The current phase
pub fn phase(&self) -> i32 {
self.y as i32
pub fn phase<P>(&self) -> P
where
P: 'static + Copy,
Q: AsPrimitive<P>,
{
self.y.as_()
}

/// Current output including wraps
pub fn y(&self) -> i64 {
pub fn y(&self) -> Q {
self.y
}
}
Expand Down

0 comments on commit fa5c2d4

Please sign in to comment.