lasprs 0.14.0

Library for Acoustic Signal Processing (Rust edition, with optional Python bindings via pyo3)
use super::*;
use crate::{siggen::source::SourceImpl, *};
use snafu::prelude::*;

type Result<T> = std::result::Result<T, SiggenError>;

/// Sine wave, with configurable frequency
#[derive(Clone, Debug)]
pub struct Sine {
    // Sampling freq \[Hz\]
    fs: StrictlyPositive,
    // current stored phase
    phase: Flt,
    // Signal frequency \[rad/s\]
    omg: StrictlyPositive,
}
impl Sine {
    /// Create new sine source signal
    ///
    /// Args:
    ///
    /// * fs: Sampling freq [Hz]
    /// *
    pub fn new(freq: Positive, fs: StrictlyPositive) -> Result<Sine> {
        ensure!(
            *freq < *fs / 2.0,
            InvalidParameterSnafu {
                param: "Frequency",
                criterion: "Sine frequency should be smaller than Nyquist frequency"
            }
        );

        Ok(Sine {
            fs,
            phase: 0.0,
            omg: StrictlyPositive::new(twopi * *freq).unwrap(), // Freq is already checked for being positive
        })
    }
}
impl SourceImpl for Sine {
    fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator<Item = &mut Flt>) {
        if *self.fs <= 0.0 {
            sig.for_each(|s| {
                *s = 0.0;
            });
            return;
        }
        sig.for_each(|s| {
            *s = Flt::sin(self.phase);
            self.phase += *self.omg / *self.fs;
            self.phase %= twopi;
        });
    }
    fn fs(&self) -> StrictlyPositive {
        self.fs
    }
}