Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pulse wave signal source functions to the signal module #151

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions dasp_signal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,21 @@ pub struct Square<S> {
phase: Phase<S>,
}

#[derive(Clone)]
pub struct Pulse12<S> {
phase: Phase<S>,
}

#[derive(Clone)]
pub struct Pulse25<S> {
phase: Phase<S>,
}

#[derive(Clone)]
pub struct Pulse75<S> {
phase: Phase<S>,
}

/// A noise signal generator.
#[derive(Clone)]
pub struct Noise {
Expand Down Expand Up @@ -1519,6 +1534,78 @@ pub fn square<S>(phase: Phase<S>) -> Square<S> {
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).pulse12();
/// 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 pulse12<S>(phase: Phase<S>) -> Pulse12<S> {
Pulse12 { 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).pulse25();
/// 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 pulse25<S>(phase: Phase<S>) -> Pulse25<S> {
Pulse25 { 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).pulse75();
/// 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 pulse75<S>(phase: Phase<S>) -> Pulse75<S> {
Pulse75 { phase: phase }
}

/// Produces a `Signal` that yields random values between -1.0..1.0.
///
/// # Example
Expand Down Expand Up @@ -1783,6 +1870,57 @@ where
}
}

impl<S> Signal for Pulse12<S>
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<S> Signal for Pulse25<S>
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<S> Signal for Pulse75<S>
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 {
Expand Down Expand Up @@ -1845,6 +1983,24 @@ where
self.phase().square()
}

/// A composable alternative to the `signal::pulse12` function.
#[inline]
pub fn pulse12(self) -> Pulse12<Self> {
self.phase().pulse12()
}

/// A composable alternative to the `signal::pulse25` function.
#[inline]
pub fn pulse25(self) -> Pulse25<Self> {
self.phase().pulse25()
}

/// A composable alternative to the `signal::pulse75` function.
#[inline]
pub fn pulse75(self) -> Pulse75<Self> {
self.phase().pulse75()
}

/// A composable alternative to the `signal::noise_simplex` function.
#[inline]
pub fn noise_simplex(self) -> NoiseSimplex<Self> {
Expand Down Expand Up @@ -1877,6 +2033,24 @@ impl ConstHz {
self.phase().square()
}

/// A composable alternative to the `signal::pulse12` function.
#[inline]
pub fn pulse12(self) -> Pulse12<Self> {
self.phase().pulse12()
}

/// A composable alternative to the `signal::pulse25` function.
#[inline]
pub fn pulse25(self) -> Pulse25<Self> {
self.phase().pulse25()
}

/// A composable alternative to the `signal::pulse75` function.
#[inline]
pub fn pulse75(self) -> Pulse75<Self> {
self.phase().pulse75()
}

/// A composable alternative to the `signal::noise_simplex` function.
#[inline]
pub fn noise_simplex(self) -> NoiseSimplex<Self> {
Expand Down Expand Up @@ -1952,6 +2126,24 @@ where
square(self)
}

/// A composable version of the `signal::pulse12` function.
#[inline]
pub fn pulse12(self) -> Pulse12<S> {
pulse12(self)
}

/// A composable version of the `signal::pulse25` function.
#[inline]
pub fn pulse25(self) -> Pulse25<S> {
pulse25(self)
}

/// A composable version of the `signal::pulse75` function.
#[inline]
pub fn pulse75(self) -> Pulse75<S> {
pulse75(self)
}

/// A composable version of the `signal::noise_simplex` function.
#[inline]
pub fn noise_simplex(self) -> NoiseSimplex<S> {
Expand Down