Skip to main content

Crate wsola

Crate wsola 

Source
Expand description

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.

§Why WSOLA (and how it works)

Naive tempo change resamples - playing samples faster shifts pitch up. WSOLA instead cuts the input into overlapping frames, lays them back down at a different spacing (closer together to speed up, further apart to slow down), and overlap-adds them with a Hann window. Placing frames at a new spacing changes duration; keeping each frame’s samples untouched preserves pitch. The “WS” part is the trick that avoids clicks: 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.

With a periodic Hann window at 50% overlap the windows sum to unity, so at tempo 1.0 (and a zero-offset match) the output reconstructs the input.

§Streaming API

TimeStretch is a streaming processor over interleaved f32 frames. Feed decoder output with push, pull stretched frames for the sink with pull, and flush at end of stream. Tempo is settable mid-stream.

use wsola::TimeStretch;
let mut ts = TimeStretch::new(44_100, 2).unwrap();
ts.set_tempo(1.5); // 1.5x faster, same pitch
ts.push(&[0.0f32; 4096]); // interleaved stereo frames from the decoder
let out = ts.pull(1024); // interleaved frames for the output sink

For a whole buffer at once, use the stretch convenience function.

Structs§

Config
Tuning for the WSOLA windows, in milliseconds. Config::default is a good starting point for speech; larger hop_ms is smoother but smears transients, larger search_ms improves waveform matching at the cost of CPU.
TimeStretch
A streaming, pitch-preserving time-stretcher over interleaved f32 frames.

Enums§

Error
Errors from constructing or driving a TimeStretch.

Constants§

MAX_TEMPO
See MIN_TEMPO.
MIN_TEMPO
Lowest and highest tempo the stretcher will honor; TimeStretch::set_tempo clamps to this range.

Functions§

stretch
Time-stretch a whole interleaved buffer in one call: pitch-preserved tempo change by tempo. Equivalent to new + set_tempo + push + pull + flush, and a good first port of call for offline use and tests.

Type Aliases§

Result
Convenience alias for results from this crate.