Skip to content

Commit

Permalink
Final documentation cleanup before publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchmindtree committed May 29, 2020
1 parent 3c862f0 commit 221b810
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 49 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

**Digital Audio Signal Processing in Rust.**

*Formerly the [`sample` crate](https://crates.io/crates/sample).*

A suite of crates providing the fundamentals for working with PCM (pulse-code
modulation) DSP (digital signal processing). In other words, `dasp` provides a
suite of low-level, high-performance tools including types, traits and functions
Expand Down
16 changes: 11 additions & 5 deletions dasp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! **dasp** is a suite of crates providing the fundamentals for working with pulse-code modulation
//! **digital audio signal processing**. In other words, **dasp** provides a suite of low-level,
//! high-performance tools including types, traits and functions for working with digital audio
//! signals.
//! **dasp** (formerly known as ***sample***) is a suite of crates providing the fundamentals for
//! working with pulse-code modulation **digital audio signal processing**. In other words,
//! **dasp** provides a suite of low-level, high-performance tools including types, traits and
//! functions for working with digital audio signals.
//!
//! Each of the **dasp** crates are re-exported under their respective
//! [modules](file:///home/mindtree/programming/rust/dasp/target/doc/dasp/index.html#modules).
Expand Down Expand Up @@ -30,6 +30,12 @@
//! within this crate. You may pick and choose between the following features for additional
//! functionality.
//!
//! - The **all** feature enables all of the following features.
//! - The **std** feature enables the std library. This is enabled by default.
//! - The **all-no-std** feature enables all of the following features (without std).
//!
//! The following features map to each of the sub-crates and their respective features.
//!
//! - The **envelope** feature enables the `dasp_envelope` crate via the
//! [envelope](./envelope/index.html) module.
//! - The **envelope-peak** feature enables peak envelope detection.
Expand Down Expand Up @@ -69,7 +75,7 @@
//! - The **window-rectangle** feature enables the
//! [**Rectangle**](./window/struct.Rectangle.html) window implementation.
//!
//! Enable all of the above features with the `--all-features` flag or with the **all** feature.
//! You can also enable all of the above features with the `--all-features` flag.
//!
//! ### no_std
//!
Expand Down
2 changes: 1 addition & 1 deletion dasp_frame/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Use the [**Frame** trait](./trait.Frame.html) to remain generic over the number of channels at
//! Use the [**Frame**](./trait.Frame.html) trait to remain generic over the number of channels at
//! a single discrete moment in time.
//!
//! Implementations are provided for all fixed-size arrays up to 32 elements in length.
Expand Down
13 changes: 4 additions & 9 deletions dasp_sample/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
//! A crate of fundamentals for audio PCM DSP.
//! Use the [**Sample**](./trait.Sample.html) trait to remain generic over sample types, easily
//! access sample type conversions, apply basic audio operations and more.
//!
//! - Use the [**Sample** trait](./trait.Sample.html) to remain generic across bit-depth.
//! - Use the [**Frame** trait](./frame/trait.Frame.html) to remain generic over channel layout.
//! - Use the [**Signal** trait](./signal/trait.Signal.html) for working with **Iterators** that yield **Frames**.
//! - Use the [**slice** module](./slice/index.html) for working with slices of **Samples** and **Frames**.
//! - See the [**conv** module](./conv/index.html) for fast conversions between slices, frames and samples.
//! - See the [**types** module](./types/index.html) for provided custom sample types.
//! - See the [**interpolate** module](./interpolate/index.html) for sample rate conversion and scaling.
//! - See the [**ring_buffer** module](./ring_buffer/index.html) for fast FIFO queue options.
//! The **Sample** trait is the core abstraction throughout dasp on which most other abstractions
//! are based.

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(core_intrinsics))]
Expand Down
90 changes: 56 additions & 34 deletions dasp_signal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,16 @@ type Rc<T> = alloc::rc::Rc<T>;
#[cfg(feature = "std")]
type Rc<T> = std::rc::Rc<T>;

/// Types that yield `Frame`s as a multi-channel PCM signal.
/// Types that yield `Frame`s of a one-or-more-channel PCM signal.
///
/// For example, `Signal` allows us to add two signals, modulate a signal's amplitude by another
/// signal, scale a signals amplitude and much more.
/// signal, scale a signal's amplitude and much more.
///
/// The **Signal** trait is inspired by the `Iterator` trait but is different in the sense that it
/// will always yield frames and will never return `None`. That said, implementors of `Signal` may
/// optionally indicate exhaustian via the `is_exhausted` method. This allows for converting
/// exhaustive signals back to iterators that are well behaved. Calling **next** on an exhausted
/// signal should always yield `Self::Frame::EQUILIBRIUM`.
pub trait Signal {
/// The `Frame` type returned by the `Signal`.
type Frame: Frame;
Expand All @@ -85,15 +91,31 @@ pub trait Signal {
///
/// # Example
///
/// An example of a mono (single-channel) signal.
///
/// ```rust
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [0.2, -0.6, 0.4];
/// let mut signal = signal::from_iter(frames.iter().cloned());
/// assert_eq!(signal.next(), 0.2);
/// assert_eq!(signal.next(), -0.6);
/// assert_eq!(signal.next(), 0.4);
/// }
/// ```
///
/// An example of a stereo (dual-channel) signal.
///
/// ```rust
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [[0.2], [-0.6], [0.4]];
/// let frames = [[0.2, 0.2], [-0.6, -0.6], [0.4, 0.4]];
/// let mut signal = signal::from_iter(frames.iter().cloned());
/// assert_eq!(signal.next(), [0.2]);
/// assert_eq!(signal.next(), [-0.6]);
/// assert_eq!(signal.next(), [0.4]);
/// assert_eq!(signal.next(), [0.2, 0.2]);
/// assert_eq!(signal.next(), [-0.6, -0.6]);
/// assert_eq!(signal.next(), [0.4, 0.4]);
/// }
/// ```
fn next(&mut self) -> Self::Frame;
Expand Down Expand Up @@ -125,15 +147,15 @@ pub trait Signal {
/// assert_eq!(sine_signal.is_exhausted(), false);
///
/// // Signals over iterators return `true` when the inner iterator is exhausted.
/// let frames = [[0.2], [-0.6], [0.4]];
/// let frames = [0.2, -0.6, 0.4];
/// let mut iter_signal = signal::from_iter(frames.iter().cloned());
/// assert_eq!(iter_signal.is_exhausted(), false);
/// iter_signal.by_ref().take(3).count();
/// assert_eq!(iter_signal.is_exhausted(), true);
///
/// // Adaptors return `true` when the first signal becomes exhausted.
/// let a = [[1], [2]];
/// let b = [[1], [2], [3], [4]];
/// let a = [1, 2];
/// let b = [1, 2, 3, 4];
/// let a_signal = signal::from_iter(a.iter().cloned());
/// let b_signal = signal::from_iter(b.iter().cloned());
/// let mut added = a_signal.add_amp(b_signal);
Expand All @@ -155,8 +177,8 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = signal::gen(|| [0.5]);
/// let mut mapper = frames.map(|f| [f[0], 0.25]);
/// let frames = signal::gen(|| 0.5);
/// let mut mapper = frames.map(|f| [f, 0.25]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
Expand Down Expand Up @@ -202,9 +224,9 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = signal::gen(|| [0.5]);
/// let more_frames = signal::gen(|| [0.25]);
/// let mut mapper = frames.zip_map(more_frames, |f, o| [f[0], o[0]]);
/// let frames = signal::gen(|| 0.5);
/// let more_frames = signal::gen(|| 0.25);
/// let mut mapper = frames.zip_map(more_frames, |f, o| [f, o]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
/// assert_eq!(mapper.next(), [0.5, 0.25]);
Expand Down Expand Up @@ -234,12 +256,12 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let a = [[0.2], [-0.6], [0.4]];
/// let b = [[0.2], [0.1], [-0.8]];
/// let a = [0.2, -0.6, 0.4];
/// let b = [0.2, 0.1, -0.8];
/// let a_signal = signal::from_iter(a.iter().cloned());
/// let b_signal = signal::from_iter(b.iter().cloned());
/// let added: Vec<_> = a_signal.add_amp(b_signal).take(3).collect();
/// assert_eq!(added, vec![[0.4], [-0.5], [-0.4]]);
/// assert_eq!(added, vec![0.4, -0.5, -0.4]);
/// }
/// ```
#[inline]
Expand All @@ -264,12 +286,12 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let a = [[0.25], [-0.8], [-0.5]];
/// let b = [[0.2], [0.5], [0.8]];
/// let a = [0.25, -0.8, -0.5];
/// let b = [0.2, 0.5, 0.8];
/// let a_signal = signal::from_iter(a.iter().cloned());
/// let b_signal = signal::from_iter(b.iter().cloned());
/// let added: Vec<_> = a_signal.mul_amp(b_signal).take(3).collect();
/// assert_eq!(added, vec![[0.05], [-0.4], [-0.4]]);
/// assert_eq!(added, vec![0.05, -0.4, -0.4]);
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -323,10 +345,10 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [[0.2], [-0.5], [-0.4], [0.3]];
/// let frames = [0.2, -0.5, -0.4, 0.3];
/// let signal = signal::from_iter(frames.iter().cloned());
/// let scaled: Vec<_> = signal.scale_amp(2.0).take(4).collect();
/// assert_eq!(scaled, vec![[0.4], [-1.0], [-0.8], [0.6]]);
/// assert_eq!(scaled, vec![0.4, -1.0, -0.8, 0.6]);
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -444,13 +466,13 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let foo = [[0.0], [1.0], [0.0], [-1.0]];
/// let foo = [0.0, 1.0, 0.0, -1.0];
/// let mut source = signal::from_iter(foo.iter().cloned());
/// let a = source.next();
/// let b = source.next();
/// let interp = Linear::new(a, b);
/// let frames: Vec<_> = source.from_hz_to_hz(interp, 1.0, 2.0).take(8).collect();
/// assert_eq!(&frames[..], &[[0.0], [0.5], [1.0], [0.5], [0.0], [-0.5], [-1.0], [-0.5]][..]);
/// assert_eq!(&frames[..], &[0.0, 0.5, 1.0, 0.5, 0.0, -0.5, -1.0, -0.5][..]);
/// }
/// ```
fn from_hz_to_hz<I>(self, interpolator: I, source_hz: f64, target_hz: f64) -> Converter<Self, I>
Expand All @@ -470,13 +492,13 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let foo = [[0.0], [1.0], [0.0], [-1.0]];
/// let foo = [0.0, 1.0, 0.0, -1.0];
/// let mut source = signal::from_iter(foo.iter().cloned());
/// let a = source.next();
/// let b = source.next();
/// let interp = Linear::new(a, b);
/// let frames: Vec<_> = source.scale_hz(interp, 0.5).take(8).collect();
/// assert_eq!(&frames[..], &[[0.0], [0.5], [1.0], [0.5], [0.0], [-0.5], [-1.0], [-0.5]][..]);
/// assert_eq!(&frames[..], &[0.0, 0.5, 1.0, 0.5, 0.0, -0.5, -1.0, -0.5][..]);
/// }
/// ```
fn scale_hz<I>(self, interpolator: I, multi: f64) -> Converter<Self, I>
Expand All @@ -498,10 +520,10 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [[0.2], [0.4]];
/// let frames = [0.2, 0.4];
/// let signal = signal::from_iter(frames.iter().cloned());
/// let delayed: Vec<_> = signal.delay(2).take(4).collect();
/// assert_eq!(delayed, vec![[0.0], [0.0], [0.2], [0.4]]);
/// assert_eq!(delayed, vec![0.0, 0.0, 0.2, 0.4]);
/// }
/// ```
fn delay(self, n_frames: usize) -> Delay<Self>
Expand Down Expand Up @@ -672,10 +694,10 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [[0.1], [0.2], [0.3], [0.4]];
/// let frames = [0.1, 0.2, 0.3, 0.4];
/// let mut signal = signal::from_iter(frames.iter().cloned()).take(2);
/// assert_eq!(signal.next(), Some([0.1]));
/// assert_eq!(signal.next(), Some([0.2]));
/// assert_eq!(signal.next(), Some(0.1));
/// assert_eq!(signal.next(), Some(0.2));
/// assert_eq!(signal.next(), None);
/// }
/// ```
Expand All @@ -695,7 +717,7 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = [[1], [2]];
/// let frames = [1, 2];
/// let signal = signal::from_iter(frames.iter().cloned());
/// assert_eq!(signal.until_exhausted().count(), 2);
/// }
Expand Down Expand Up @@ -802,9 +824,9 @@ pub trait Signal {
/// use dasp_signal::{self as signal, Signal};
///
/// fn main() {
/// let frames = vec![[0], [1], [2], [3]];
/// let frames = vec![0, 1, 2, 3];
/// let offset_frames = signal::lift(frames, |signal| signal.offset_amp(2));
/// assert_eq!(offset_frames.collect::<Vec<_>>(), vec![[2], [3], [4], [5]]);
/// assert_eq!(offset_frames.collect::<Vec<_>>(), vec![2, 3, 4, 5]);
/// }
/// ```
pub fn lift<I, F, S>(iter: I, f: F) -> UntilExhausted<S>
Expand Down

0 comments on commit 221b810

Please sign in to comment.