oscillation 0.1.1

Oscillators and a collection of waveforms for real-time usage.
Documentation
use num_traits::{Float, FloatConst};

use crate::waveform::Waveform;

use super::{Direct, OscillatorState, WaveDTC};

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
pub struct DirectDTC<F, W>
where
    F: Float + FloatConst,
    W: Waveform<F>
{
    pub waveform: W,
    pub duty_cycle: F
}

impl<F, W> From<W> for DirectDTC<F, W>
where
    F: Float + FloatConst,
    W: Waveform<F>
{
    fn from(waveform: W) -> Self
    {
        Direct::from(waveform).into()
    }
}
impl<F, W> From<Direct<W>> for DirectDTC<F, W>
where
    F: Float + FloatConst,
    W: Waveform<F>
{
    fn from(value: Direct<W>) -> Self
    {
        value.with_dtc(crate::duty_cycle_default())
    }
}

impl<F, W> OscillatorState<F> for DirectDTC<F, W>
where
    F: Float + FloatConst,
    W: Waveform<F>
{
    type Waveform = W;

    type WithDTC = DirectDTC<F, W>;
    type WithoutDTC = Direct<W>;

    type WithWavetable<const N: usize> = WaveDTC<F, W, N>;
    type WithoutWavetable = DirectDTC<F, W>;

    type WithWaveform<WW> = DirectDTC<F, WW>
    where
        WW: Waveform<F>;

    fn next(&mut self, theta: F, omega: F, rate: F) -> F
    {
        let zero = F::zero();
        let pi = F::PI();
        let nyq = pi*rate;
        if nyq <= omega
        {
            return zero
        }

        self.waveform.waveform_with_dtc(theta, self.duty_cycle)
    }

    fn duty_cycle(&self) -> F
    {
        self.duty_cycle
    }

    fn waveform(&self) -> &Self::Waveform
    {
        &self.waveform
    }
    fn waveform_mut(&mut self) -> &mut Self::Waveform
    {
        &mut self.waveform
    }

    fn with_dtc(mut self, duty_cycle: F) -> Self::WithDTC
    {
        self.duty_cycle = duty_cycle;
        self
    }
    fn without_dtc(self) -> Self::WithoutDTC
    {
        let Self {waveform, duty_cycle: _} = self;
        Direct {
            waveform
        }
    }

    fn with_wavetable<const N: usize>(self) -> Self::WithWavetable<N>
    {
        self.into()
    }
    fn without_wavetable(self) -> Self::WithoutWavetable
    {
        self
    }

    fn map_waveform<WW>(self, waveform: impl FnOnce(Self::Waveform) -> WW) -> Self::WithWaveform<WW>
    where
        WW: Waveform<F>
    {
        DirectDTC {
            waveform: waveform(self.waveform),
            duty_cycle: self.duty_cycle
        }
    }
}