diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..76e3f8e Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dasp.iml b/.idea/dasp.iml new file mode 100644 index 0000000..1034b3a --- /dev/null +++ b/.idea/dasp.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..05a44bf --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index dacb16d..6951bbc 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -143,6 +143,7 @@ pub trait Signal { /// /// fn main() { /// // Infinite signals always return `false`. + /// use dasp_signal::Step; /// let sine_signal = signal::rate(44_100.0).const_hz(400.0).sine(); /// assert_eq!(sine_signal.is_exhausted(), false); /// @@ -960,6 +961,16 @@ pub struct NoiseSimplex { phase: Phase, } +// A signal generator with offset phase. +#[derive(Clone)] +pub struct OffsetPhase +where + S: Signal + Step, +{ + step: S, + offset: f64, +} + /// An iterator that yields the sum of the frames yielded by both `other` and `self` in lock-step. #[derive(Clone)] pub struct AddAmp { @@ -1444,10 +1455,7 @@ pub fn phase(step: S) -> Phase where S: Step, { - Phase { - step: step, - next: 0.0, - } + Phase { step, next: 0.0 } } /// Creates a frame `Rate` (aka sample rate) representing the rate at which a signal may be @@ -1850,6 +1858,34 @@ where pub fn noise_simplex(self) -> NoiseSimplex { self.phase().noise_simplex() } + + /// Offsets the phase of a signal by the specified value, between 0.0 and 1.0 by default. + /// + /// # Example + /// + /// ```rust + /// use dasp_signal::{self as signal, Signal}; + /// + /// fn main() { + /// let step = signal::rate(4.0).const_hz(1.0).offset_phase(0.25); + /// let mut phase = step.phase(); + /// assert_eq!(phase.next(), 0.25); + /// assert_eq!(phase.next(), 0.5); + /// assert_eq!(phase.next(), 0.75); + /// assert_eq!(phase.next(), 0.0); + /// assert_eq!(phase.next(), 0.25); + /// assert_eq!(phase.next(), 0.5); + /// } + /// ``` + #[inline] + pub fn offset_phase(self, offset: f64) -> OffsetPhase { + let rem = 1.0; + + OffsetPhase { + step: self, + offset: offset % rem, + } + } } impl ConstHz { @@ -1882,6 +1918,16 @@ impl ConstHz { pub fn noise_simplex(self) -> NoiseSimplex { self.phase().noise_simplex() } + + #[inline] + pub fn offset_phase(self, offset: f64) -> OffsetPhase { + let rem = 1.0; + + OffsetPhase { + step: self, + offset: offset % rem, + } + } } /// Types that may be used to give a phase step size based on some `hz / sample rate`. @@ -2097,6 +2143,42 @@ where } } +impl OffsetPhase { + /// Construct a `Phase` iterator that is incremented via the constant step size, `self.step`, + /// and takes an offset into account. + #[inline] + pub fn phase(self) -> Phase { + Phase { + step: self.step, + next: self.offset, + } + } + + /// A composable alternative to the `signal::sine` function. + #[inline] + pub fn sine(self) -> Sine { + self.phase().sine() + } + + /// A composable alternative to the `signal::saw` function. + #[inline] + pub fn saw(self) -> Saw { + self.phase().saw() + } + + /// A composable alternative to the `signal::square` function. + #[inline] + pub fn square(self) -> Square { + self.phase().square() + } + + /// A composable alternative to the `signal::noise_simplex` function. + #[inline] + pub fn noise_simplex(self) -> NoiseSimplex { + self.phase().noise_simplex() + } +} + impl Signal for AddAmp where A: Signal,