• Stars
    star
    720
  • Rank 60,704 (Top 2 %)
  • Language
    Rust
  • License
    Other
  • Created over 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The fundamentals for Digital Audio Signal Processing. Formerly `sample`.

dasp Actions Status docs.rs

Digital Audio Signal Processing in Rust.

Formerly the sample crate.

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 for working with digital audio signals.

The dasp libraries require no dynamic allocations1 and have no dependencies. The goal is to design a library akin to the std, but for audio DSP; keeping the focus on portable and fast fundamentals.

1: Besides the feature-gated SignalBus trait, which is occasionally useful when converting a Signal tree into a directed acyclic graph.

Find the API documentation here.

Crates

dasp is a modular collection of crates, allowing users to select the precise set of tools required for their project. The following crates are included within this repository:

Library Links Description
dasp Crates.io docs.rs Top-level API with features for all crates.
dasp_sample Crates.io docs.rs Sample trait, types, conversions and operations.
dasp_frame Crates.io docs.rs Frame trait, types, conversions and operations.
dasp_slice Crates.io docs.rs Conversions and ops for slices of samples/frames.
dasp_ring_buffer Crates.io docs.rs Simple fixed and bounded ring buffers.
dasp_peak Crates.io docs.rs Peak detection with half/full pos/neg wave rectifiers.
dasp_rms Crates.io docs.rs RMS detection with configurable window.
dasp_envelope Crates.io docs.rs Envelope detection with peak and RMS impls.
dasp_interpolate Crates.io docs.rs Inter-frame rate interpolation (linear, sinc, etc).
dasp_window Crates.io docs.rs Windowing function abstraction (hann, rectangle).
dasp_signal Crates.io docs.rs Iterator-like API for streams of audio frames.
dasp_graph Crates.io docs.rs For working with modular, dynamic audio graphs.

deps-graph

Red dotted lines indicate optional dependencies, while black lines indicate required dependencies.

Features

Use the Sample trait to convert between and remain generic over any bit-depth in an optimal, performance-sensitive manner. Implementations are provided for all signed integer, unsigned integer and floating point primitive types along with some custom types including 11, 20, 24 and 48-bit signed and unsigned unpacked integers. For example:

assert_eq!((-1.0).to_sample::<u8>(), 0);
assert_eq!(0.0.to_sample::<u8>(), 128);
assert_eq!(0i32.to_sample::<u32>(), 2_147_483_648);
assert_eq!(I24::new(0).unwrap(), Sample::from_sample(0.0));
assert_eq!(0.0, Sample::EQUILIBRIUM);

Use the Frame trait to remain generic over the number of channels at a discrete moment in time. Implementations are provided for all fixed-size arrays up to 32 elements in length.

let foo = [0.1, 0.2, -0.1, -0.2];
let bar = foo.scale_amp(2.0);
assert_eq!(bar, [0.2, 0.4, -0.2, -0.4]);

assert_eq!(Mono::<f32>::EQUILIBRIUM, [0.0]);
assert_eq!(Stereo::<f32>::EQUILIBRIUM, [0.0, 0.0]);
assert_eq!(<[f32; 3]>::EQUILIBRIUM, [0.0, 0.0, 0.0]);

let foo = [0i16, 0];
let bar: [u8; 2] = foo.map(Sample::to_sample);
assert_eq!(bar, [128u8, 128]);

Use the Signal trait (enabled by the "signal" feature) for working with infinite-iterator-like types that yield Frames. Signal provides methods for adding, scaling, offsetting, multiplying, clipping, generating, monitoring and buffering streams of Frames. Working with Signals allows for easy, readable creation of rich and complex DSP graphs with a simple and familiar API.

// Clip to an amplitude of 0.9.
let frames = [[1.2, 0.8], [-0.7, -1.4]];
let clipped: Vec<_> = signal::from_iter(frames.iter().cloned()).clip_amp(0.9).take(2).collect();
assert_eq!(clipped, vec![[0.9, 0.8], [-0.7, -0.9]]);

// Add `a` with `b` and yield the result.
let a = [0.2, -0.6, 0.5];
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<f32> = a_signal.add_amp(b_signal).take(3).collect();
assert_eq!(added, vec![0.4, -0.5, -0.3]);

// Scale the playback rate by `0.5`.
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][..]);

// Convert a signal to its RMS.
let signal = signal::rate(44_100.0).const_hz(440.0).sine();;
let ring_buffer = ring_buffer::Fixed::from([0.0; WINDOW_SIZE]);
let mut rms_signal = signal.rms(ring_buffer);

The signal module also provides a series of Signal source types, including:

  • FromIterator
  • FromInterleavedSamplesIterator
  • Equilibrium (silent signal)
  • Phase
  • Sine
  • Saw
  • Square
  • Noise
  • NoiseSimplex
  • Gen (generate frames from a Fn() -> F)
  • GenMut (generate frames from a FnMut() -> F)

Use the slice module functions (enabled via the "slice" feature) for processing chunks of Frames. Conversion functions are provided for safely converting between slices of interleaved Samples and slices of Frames without requiring any allocation. For example:

let frames = &[[0.0, 0.5], [0.0, -0.5]][..];
let samples = slice::to_sample_slice(frames);
assert_eq!(samples, &[0.0, 0.5, 0.0, -0.5][..]);

let samples = &[0.0, 0.5, 0.0, -0.5][..];
let frames = slice::to_frame_slice(samples);
assert_eq!(frames, Some(&[[0.0, 0.5], [0.0, -0.5]][..]));

let samples = &[0.0, 0.5, 0.0][..];
let frames = slice::to_frame_slice(samples);
assert_eq!(frames, None::<&[[f32; 2]]>);

The signal::interpolate module provides a Converter type, for converting and interpolating the rate of Signals. This can be useful for both sample rate conversion and playback rate multiplication. Converters can use a range of interpolation methods, with Floor, Linear, and Sinc interpolation provided in the library.

The ring_buffer module provides generic Fixed and Bounded ring buffer types, both of which may be used with owned, borrowed, stack and allocated buffers.

The peak module can be used for monitoring the peak of a signal. Provided peak rectifiers include full_wave, positive_half_wave and negative_half_wave.

The rms module provides a flexible Rms type that can be used for RMS (root mean square) detection. Any Fixed ring buffer can be used as the window for the RMS detection.

The envelope module provides a Detector type (also known as a Follower) that allows for detecting the envelope of a signal. Detector is generic over the type of Detection - Rms and Peak detection are provided. For example:

let signal = signal::rate(4.0).const_hz(1.0).sine();
let attack = 1.0;
let release = 1.0;
let detector = envelope::Detector::peak(attack, release);
let mut envelope = signal.detect_envelope(detector);
assert_eq!(
    envelope.take(4).collect::<Vec<_>>(),
    vec![0.0, 0.6321205496788025, 0.23254416035257117, 0.7176687675647109]
);

no_std

All crates may be compiled with and without the std library. The std library is enabled by default, however it may be disabled via --no-default-features.

To enable all of a crate's features without the std library, you may use --no-default-features --features "all-no-std".

Please note that some of the crates require the core_intrinsics feature in order to be able to perform operations like sin, cos and powf32 in a no_std context. This means that these crates require the nightly toolchain in order to build in a no_std context.

Contributing

If dasp is missing types, conversions or other fundamental functionality that you wish it had, feel free to open an issue or pull request! The more hands on deck, the merrier :)

License

Licensed under either of

at your option.

Contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

More Repositories

1

cpal

Cross-platform audio I/O library in pure Rust
Rust
2,364
star
2

rodio

Rust audio playback library
Rust
1,613
star
3

vst-rs

VST 2.4 API implementation in rust. Create plugins or hosts. Previously rust-vst on the RustDSP group.
Rust
973
star
4

rust-portaudio

PortAudio bindings and wrappers for Rust.
Rust
359
star
5

deepspeech-rs

Rust bindings for the deepspeech library
Rust
295
star
6

dsp-chain

A library for chaining together multiple audio dsp processors/generators, written in Rust!
Rust
287
star
7

lewton

Rust vorbis decoder
Rust
250
star
8

vst3-sys

Raw Bindings to the VST3 API
Rust
210
star
9

rust-jack

Decent jack bindings for rust
Rust
198
star
10

baseview

low-level window system interface for audio plugin UIs
Rust
184
star
11

synth

A polyphonic Synth type whose multiple oscillators generate sound via amplitude and frequency envelopes, implemented in Rust. DEPRECATED: This is a very old crate with very old design patterns and is no longer maintained. You might be interested in checking out `dasp` for composing your own synth instead.
Rust
172
star
12

coreaudio-rs

A friendly rust interface to Apple's Core Audio API.
Rust
169
star
13

rust-lv2

A safe, fast, and modular framework to create LV2 plugins, written in Rust
Rust
150
star
14

audrey

A crate to simplify reading, writing and converting between a variety of audio formats.
Rust
114
star
15

ogg

Ogg container decoder and encoder written in pure Rust
Rust
97
star
16

rimd

Library for handling Midi and Standard Midi Files in Rust
Rust
77
star
17

wmidi

Rust midi encoding and decoding library.
Rust
63
star
18

pitch_calc

A library for musical pitch conversions! Provides functions and methods for converting between frequency (hz), midi-step, letter-octave and mels.
Rust
60
star
19

coreaudio-sys

Raw bindings to the OSX CoreAudio framework generated by bindgen (see coreaudio-rs for a more rust-esque wrapper).
Rust
59
star
20

sound_stream

A Rust audio IO stream in the style of an "Event Iterator" driven by PortAudio.
Rust
57
star
21

time_calc

A library for music/DSP time conversions! Provides functions and methods for converting between ticks, ms, samples, bars, beats and measures.
Rust
49
star
22

musical_keyboard

A small lib for converting keyboard input into musical notes.
Rust
26
star
23

mp3

Rust MP3 decoder project
Rust
23
star
24

sampler

A polyphonic sampler instrument that supports unique sample mappings across both frequency and velocity ranges. DEPRECATED: This is a very old crate with very old design patterns and is no longer maintained. You might be interested in checking out `dasp` for composing your own sampler instead.
Rust
23
star
25

areweaudioyet

Are We Audio Yet?
CSS
18
star
26

simplemad

A Rust interface for the MPEG audio (MP1, MP2, MP3) decoding library libmad
Shell
17
star
27

caf

Rust decoder for Apple's Core Audio Format (CAF)
Rust
14
star
28

envelope

An interpolatable Envelope type along with a generic 2D Point, useful for controlling parameters over time.
Rust
13
star
29

website

Website for all things audio in the Rust programming language
HTML
10
star
30

vst2-sys

Bindings for the VST 2.4 API.
Rust
9
star
31

instrument

Converts discrete note events to a continuous signal of amplitude and frequency frames over N number of voices.
Rust
8
star
32

rnnoise-c

Rust bindings to Xiph's rnnoise denoising library
Rust
7
star
33

rms

A simple type for calculating and storing the RMS given some buffer of interleaved audio samples.
Rust
7
star
34

volume

A simple dsp-chain node for multiplying the amplitude of the output buffer by some volume.
Rust
6
star
35

panning

A variety of utilities related to audio panning in Rust.
Rust
5
star
36

lyra

Feature extraction POC
Rust
4
star