wsola 0.1.0

Pitch-preserved audio time-stretch (WSOLA), pure Rust, no C
Documentation
  • Coverage
  • 100%
    27 out of 27 items documented2 out of 17 items with examples
  • Size
  • Source code size: 102.79 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 687.6 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 9s Average build duration of successful builds.
  • all releases: 9s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • jhheider/pdcst
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • jhheider

wsola

Pitch-preserved audio time-stretch (WSOLA), pure Rust, no C.

Change the tempo of an audio stream without changing its pitch - speed a podcast to 1.5x without the chipmunk effect. The engine is WSOLA (Waveform Similarity Overlap-Add): a time-domain method that is real-time capable, good on speech, and far simpler than a phase vocoder.

  • Pure Rust, one small dependency (thiserror), no C toolchain or -sys crates.
  • Streaming and one-shot APIs over interleaved f32 frames.
  • Live tempo changes (set the tempo mid-stream).
  • Property-tested; streaming output is bit-identical to one-shot.

Usage

Streaming (feed decoder output, pull frames for the sink):

use wsola::TimeStretch;

let mut ts = TimeStretch::new(44_100, 2).unwrap(); // sample rate, channels
ts.set_tempo(1.5);                                 // 1.5x faster, same pitch
ts.push(&[0.0f32; 4096]);                          // interleaved stereo frames
let out = ts.pull(1024);                           // interleaved frames out
// ... at end of stream:
let tail = ts.flush();

One-shot (stretch a whole buffer):

use wsola::stretch;

let input = vec![0.0f32; 44_100 * 2]; // 1s of stereo
let out = stretch(&input, 44_100, 2, 1.5);

Tempo is a multiplier: > 1.0 is faster/shorter, < 1.0 is slower/longer, and 1.0 reconstructs the input. Interleaved f32 in, interleaved f32 out.

How it works

Naive tempo change resamples, which shifts pitch. WSOLA instead cuts the input into overlapping frames, lays them back down at a different spacing (closer to speed up, further apart to slow down), and overlap-adds them with a Hann window. New spacing changes duration; leaving each frame's samples untouched preserves pitch. Before laying down each frame it searches a small window of nearby input positions for the segment whose waveform best continues the previous frame, so the overlap-add joins coherent waveforms instead of fighting phases - that is the "waveform similarity" that avoids clicks.

See the crate docs for the full API and the algorithm notes.

License

MIT.