From 9a0e70a6be2fd073100fbf3a9ef39035b2a9ff43 Mon Sep 17 00:00:00 2001 From: Aoife Date: Fri, 5 Feb 2021 01:11:27 -0500 Subject: [PATCH 1/5] add pulse wave signal source functions to the signal module I added three pulse wave source functions to the dasp::signal module, that I felt would be useful. I chose to add a selection 12.5%, 25%, and 75% duty cycle pulse waves. My reasoning for this was due to those 3, (plus 50%, as standard Square Wave) being the most common in chiptune, and old gaming APU's. Initially I tried extending the signal module in my own project, but came across some difficulty trying to implement it as a trait. --- dasp_signal/src/lib.rs | 192 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index da36d9f2..983cd8c3 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -949,6 +949,21 @@ pub struct Square { phase: Phase, } +#[derive(Clone)] +pub struct Pulse1 { + phase: Phase, +} + +#[derive(Clone)] +pub struct Pulse2 { + phase: Phase, +} + +#[derive(Clone)] +pub struct Pulse3 { + phase: Phase, +} + /// A noise signal generator. #[derive(Clone)] pub struct Noise { @@ -1519,6 +1534,78 @@ pub fn square(phase: Phase) -> Square { Square { phase: phase } } +/// Produces a `Signal` that yields a 12.5% duty cycle pulse wave oscillating at the given hz. +/// +/// # Example +/// +/// ```rust +/// use dasp_signal::{self as signal, Signal}; +/// +/// fn main() { +/// // Generates a square wave signal at 1hz to be sampled 8 times per second. +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse1(); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// } +/// ``` +pub fn pulse1(phase: Phase) -> Pulse1 { + Pulse1 { phase: phase } +} + +/// Produces a `Signal` that yields a 25% duty cycle pulse wave oscillating at the given hz. +/// +/// # Example +/// +/// ```rust +/// use dasp_signal::{self as signal, Signal}; +/// +/// fn main() { +/// // Generates a square wave signal at 1hz to be sampled 8 times per second. +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse2(); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// } +/// ``` +pub fn pulse2(phase: Phase) -> Pulse2 { + Pulse2 { phase: phase } +} + +/// Produces a `Signal` that yields a 75% duty cycle pulse wave oscillating at the given hz. +/// +/// # Example +/// +/// ```rust +/// use dasp_signal::{self as signal, Signal}; +/// +/// fn main() { +/// // Generates a square wave signal at 1hz to be sampled 8 times per second. +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse1(); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), 1.0); +/// assert_eq!(signal.next(), -1.0); +/// assert_eq!(signal.next(), -1.0); +/// } +/// ``` +pub fn pulse3(phase: Phase) -> Pulse3 { + Pulse3 { phase: phase } +} + /// Produces a `Signal` that yields random values between -1.0..1.0. /// /// # Example @@ -1783,6 +1870,57 @@ where } } +impl Signal for Pulse1 +where + S: Step, +{ + type Frame = f64; + + #[inline] + fn next(&mut self) -> Self::Frame { + let phase = self.phase.next_phase(); + if phase < 0.125 { + 1.0 + } else { + -1.0 + } + } +} + +impl Signal for Pulse2 +where + S: Step, +{ + type Frame = f64; + + #[inline] + fn next(&mut self) -> Self::Frame { + let phase = self.phase.next_phase(); + if phase < 0.25 { + 1.0 + } else { + -1.0 + } + } +} + +impl Signal for Pulse3 +where + S: Step, +{ + type Frame = f64; + + #[inline] + fn next(&mut self) -> Self::Frame { + let phase = self.phase.next_phase(); + if phase < 0.75 { + 1.0 + } else { + -1.0 + } + } +} + impl Rate { /// Create a `ConstHz` signal which consistently yields `hz / rate`. pub fn const_hz(self, hz: f64) -> ConstHz { @@ -1845,6 +1983,24 @@ where self.phase().square() } + /// A composable alternative to the `signal::pulse1` function. + #[inline] + pub fn pulse1(self) -> Pulse1 { + self.phase().pulse1() + } + + /// A composable alternative to the `signal::pulse2` function. + #[inline] + pub fn pulse2(self) -> Pulse2 { + self.phase().pulse2() + } + + /// A composable alternative to the `signal::pulse3` function. + #[inline] + pub fn pulse3(self) -> Pulse3 { + self.phase().pulse3() + } + /// A composable alternative to the `signal::noise_simplex` function. #[inline] pub fn noise_simplex(self) -> NoiseSimplex { @@ -1877,6 +2033,24 @@ impl ConstHz { self.phase().square() } + /// A composable alternative to the `signal::pulse1` function. + #[inline] + pub fn pulse1(self) -> Pulse1 { + self.phase().pulse1() + } + + /// A composable alternative to the `signal::pulse2` function. + #[inline] + pub fn pulse2(self) -> Pulse2 { + self.phase().pulse2() + } + + /// A composable alternative to the `signal::pulse3` function. + #[inline] + pub fn pulse3(self) -> Pulse3 { + self.phase().pulse3() + } + /// A composable alternative to the `signal::noise_simplex` function. #[inline] pub fn noise_simplex(self) -> NoiseSimplex { @@ -1952,6 +2126,24 @@ where square(self) } + /// A composable version of the `signal::pulse1` function. + #[inline] + pub fn pulse1(self) -> Pulse1 { + pulse1(self) + } + + /// A composable version of the `signal::pulse2` function. + #[inline] + pub fn pulse2(self) -> Pulse2 { + pulse2(self) + } + + /// A composable version of the `signal::pulse3` function. + #[inline] + pub fn pulse3(self) -> Pulse3 { + pulse3(self) + } + /// A composable version of the `signal::noise_simplex` function. #[inline] pub fn noise_simplex(self) -> NoiseSimplex { From bee8fdd6ae82156a0331a891d59c7f84afa62220 Mon Sep 17 00:00:00 2001 From: Aoife Date: Fri, 5 Feb 2021 11:37:39 -0500 Subject: [PATCH 2/5] fix pulse3 example --- dasp_signal/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index 983cd8c3..8d8628bc 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -1591,7 +1591,7 @@ pub fn pulse2(phase: Phase) -> Pulse2 { /// /// fn main() { /// // Generates a square wave signal at 1hz to be sampled 8 times per second. -/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse1(); +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse3(); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), 1.0); From 97eb4b763ef376fe9fa60860b472405bcfe36b6a Mon Sep 17 00:00:00 2001 From: Aoife Date: Fri, 5 Feb 2021 11:52:42 -0500 Subject: [PATCH 3/5] Change pulse struct and function names --- dasp_signal/src/lib.rs | 84 +++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index 8d8628bc..92292252 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -950,17 +950,17 @@ pub struct Square { } #[derive(Clone)] -pub struct Pulse1 { +pub struct Pulse12 { phase: Phase, } #[derive(Clone)] -pub struct Pulse2 { +pub struct Pulse25 { phase: Phase, } #[derive(Clone)] -pub struct Pulse3 { +pub struct Pulse75 { phase: Phase, } @@ -1543,7 +1543,7 @@ pub fn square(phase: Phase) -> Square { /// /// fn main() { /// // Generates a square wave signal at 1hz to be sampled 8 times per second. -/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse1(); +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse12(); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), -1.0); /// assert_eq!(signal.next(), -1.0); @@ -1554,8 +1554,8 @@ pub fn square(phase: Phase) -> Square { /// assert_eq!(signal.next(), -1.0); /// } /// ``` -pub fn pulse1(phase: Phase) -> Pulse1 { - Pulse1 { phase: phase } +pub fn pulse12(phase: Phase) -> Pulse12 { + pulse12 { phase: phase } } /// Produces a `Signal` that yields a 25% duty cycle pulse wave oscillating at the given hz. @@ -1567,7 +1567,7 @@ pub fn pulse1(phase: Phase) -> Pulse1 { /// /// fn main() { /// // Generates a square wave signal at 1hz to be sampled 8 times per second. -/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse2(); +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse25(); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), -1.0); @@ -1578,8 +1578,8 @@ pub fn pulse1(phase: Phase) -> Pulse1 { /// assert_eq!(signal.next(), -1.0); /// } /// ``` -pub fn pulse2(phase: Phase) -> Pulse2 { - Pulse2 { phase: phase } +pub fn pulse25(phase: Phase) -> Pulse25 { + pulse25 { phase: phase } } /// Produces a `Signal` that yields a 75% duty cycle pulse wave oscillating at the given hz. @@ -1591,7 +1591,7 @@ pub fn pulse2(phase: Phase) -> Pulse2 { /// /// fn main() { /// // Generates a square wave signal at 1hz to be sampled 8 times per second. -/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse3(); +/// let mut signal = signal::rate(8.0).const_hz(1.0).pulse75(); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), 1.0); /// assert_eq!(signal.next(), 1.0); @@ -1602,8 +1602,8 @@ pub fn pulse2(phase: Phase) -> Pulse2 { /// assert_eq!(signal.next(), -1.0); /// } /// ``` -pub fn pulse3(phase: Phase) -> Pulse3 { - Pulse3 { phase: phase } +pub fn pulse75(phase: Phase) -> Pulse75 { + pulse75 { phase: phase } } /// Produces a `Signal` that yields random values between -1.0..1.0. @@ -1870,7 +1870,7 @@ where } } -impl Signal for Pulse1 +impl Signal for Pulse12 where S: Step, { @@ -1887,7 +1887,7 @@ where } } -impl Signal for Pulse2 +impl Signal for Pulse25 where S: Step, { @@ -1904,7 +1904,7 @@ where } } -impl Signal for Pulse3 +impl Signal for Pulse75 where S: Step, { @@ -1983,22 +1983,22 @@ where self.phase().square() } - /// A composable alternative to the `signal::pulse1` function. + /// A composable alternative to the `signal::pulse12` function. #[inline] - pub fn pulse1(self) -> Pulse1 { - self.phase().pulse1() + pub fn pulse12(self) -> pulse12 { + self.phase().pulse12() } - /// A composable alternative to the `signal::pulse2` function. + /// A composable alternative to the `signal::pulse25` function. #[inline] - pub fn pulse2(self) -> Pulse2 { - self.phase().pulse2() + pub fn pulse25(self) -> pulse25 { + self.phase().pulse25() } - /// A composable alternative to the `signal::pulse3` function. + /// A composable alternative to the `signal::pulse75` function. #[inline] - pub fn pulse3(self) -> Pulse3 { - self.phase().pulse3() + pub fn pulse75(self) -> pulse75 { + self.phase().pulse75() } /// A composable alternative to the `signal::noise_simplex` function. @@ -2033,22 +2033,22 @@ impl ConstHz { self.phase().square() } - /// A composable alternative to the `signal::pulse1` function. + /// A composable alternative to the `signal::pulse12` function. #[inline] - pub fn pulse1(self) -> Pulse1 { - self.phase().pulse1() + pub fn pulse12(self) -> pulse12 { + self.phase().pulse12() } - /// A composable alternative to the `signal::pulse2` function. + /// A composable alternative to the `signal::pulse25` function. #[inline] - pub fn pulse2(self) -> Pulse2 { - self.phase().pulse2() + pub fn pulse25(self) -> pulse25 { + self.phase().pulse25() } - /// A composable alternative to the `signal::pulse3` function. + /// A composable alternative to the `signal::pulse75` function. #[inline] - pub fn pulse3(self) -> Pulse3 { - self.phase().pulse3() + pub fn pulse75(self) -> pulse75 { + self.phase().pulse75() } /// A composable alternative to the `signal::noise_simplex` function. @@ -2126,22 +2126,22 @@ where square(self) } - /// A composable version of the `signal::pulse1` function. + /// A composable version of the `signal::pulse12` function. #[inline] - pub fn pulse1(self) -> Pulse1 { - pulse1(self) + pub fn pulse12(self) -> pulse12 { + pulse12(self) } - /// A composable version of the `signal::pulse2` function. + /// A composable version of the `signal::pulse25` function. #[inline] - pub fn pulse2(self) -> Pulse2 { - pulse2(self) + pub fn pulse25(self) -> pulse25 { + pulse25(self) } - /// A composable version of the `signal::pulse3` function. + /// A composable version of the `signal::pulse75` function. #[inline] - pub fn pulse3(self) -> Pulse3 { - pulse3(self) + pub fn pulse75(self) -> pulse75 { + pulse75(self) } /// A composable version of the `signal::noise_simplex` function. From 702db95ccdb646737ed386ce1d20a2fee16ce097 Mon Sep 17 00:00:00 2001 From: Aoife Date: Fri, 5 Feb 2021 11:56:56 -0500 Subject: [PATCH 4/5] Fixed missed return name change --- dasp_signal/src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index 92292252..38596ed8 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -1985,19 +1985,19 @@ where /// A composable alternative to the `signal::pulse12` function. #[inline] - pub fn pulse12(self) -> pulse12 { + pub fn pulse12(self) -> Pulse12 { self.phase().pulse12() } /// A composable alternative to the `signal::pulse25` function. #[inline] - pub fn pulse25(self) -> pulse25 { + pub fn pulse25(self) -> Pulse25 { self.phase().pulse25() } /// A composable alternative to the `signal::pulse75` function. #[inline] - pub fn pulse75(self) -> pulse75 { + pub fn pulse75(self) -> Pulse75 { self.phase().pulse75() } @@ -2035,19 +2035,19 @@ impl ConstHz { /// A composable alternative to the `signal::pulse12` function. #[inline] - pub fn pulse12(self) -> pulse12 { + pub fn pulse12(self) -> Pulse12 { self.phase().pulse12() } /// A composable alternative to the `signal::pulse25` function. #[inline] - pub fn pulse25(self) -> pulse25 { + pub fn pulse25(self) -> Pulse25 { self.phase().pulse25() } /// A composable alternative to the `signal::pulse75` function. #[inline] - pub fn pulse75(self) -> pulse75 { + pub fn pulse75(self) -> Pulse75 { self.phase().pulse75() } @@ -2128,19 +2128,19 @@ where /// A composable version of the `signal::pulse12` function. #[inline] - pub fn pulse12(self) -> pulse12 { + pub fn pulse12(self) -> Pulse12 { pulse12(self) } /// A composable version of the `signal::pulse25` function. #[inline] - pub fn pulse25(self) -> pulse25 { + pub fn pulse25(self) -> Pulse25 { pulse25(self) } /// A composable version of the `signal::pulse75` function. #[inline] - pub fn pulse75(self) -> pulse75 { + pub fn pulse75(self) -> Pulse75 { pulse75(self) } From 769b02d3ddb78ce8f5aae68031cd05ec377b45c3 Mon Sep 17 00:00:00 2001 From: Aoife Date: Fri, 5 Feb 2021 12:01:20 -0500 Subject: [PATCH 5/5] Fixed functions not returning the correct Struct --- dasp_signal/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index 38596ed8..181b3458 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -1555,7 +1555,7 @@ pub fn square(phase: Phase) -> Square { /// } /// ``` pub fn pulse12(phase: Phase) -> Pulse12 { - pulse12 { phase: phase } + Pulse12 { phase: phase } } /// Produces a `Signal` that yields a 25% duty cycle pulse wave oscillating at the given hz. @@ -1579,7 +1579,7 @@ pub fn pulse12(phase: Phase) -> Pulse12 { /// } /// ``` pub fn pulse25(phase: Phase) -> Pulse25 { - pulse25 { phase: phase } + Pulse25 { phase: phase } } /// Produces a `Signal` that yields a 75% duty cycle pulse wave oscillating at the given hz. @@ -1603,7 +1603,7 @@ pub fn pulse25(phase: Phase) -> Pulse25 { /// } /// ``` pub fn pulse75(phase: Phase) -> Pulse75 { - pulse75 { phase: phase } + Pulse75 { phase: phase } } /// Produces a `Signal` that yields random values between -1.0..1.0.