Safe Rust bindings for FluCoMa (Fluid Corpus Manipulation), a set of C++ audio analysis and transformation algorithms developed for creative music applications.
The underlying flucoma-core library covers spectral
analysis, source separation, feature extraction, and event segmentation. This crate exposes those
algorithms through idiomatic Rust wrappers with owned types, Result-based error handling, and no
unsafe code in user-facing APIs.
This is a work in progress.
See STATUS.md for which functions are wrapped and which are not.
Note that FluCoMa ML and Statistics functions are not wrapped on purpose. There are various great Rust native libs out there which can be used in combination with the existing wrapped FluCoMa tools.
See EXTEND.md on how to create new wrappers. Pull requests are welcome!
- Rust toolchain (stable)
- C++17 compatible compiler (MSVC, clang++, or g++)
- CMake (used to fetch and build Eigen, HISSTools, Spectra, and foonathan/memory)
Clone with
git clone --recurse-submodules <url>. The flucoma-core C++ source is included as a git submodule undervendor/flucoma-core/.
Detects onsets in an audio file, computes a mean mel-band vector per slice, and writes timbrally unique slices as individual WAV files. Slices that are too similar to an already-kept slice are skipped.
cargo run --release --example unique-slices -- input.wavOutput: <input_stem>_slices/slice1_<start>_<end>.wav, etc.
Separates an audio file into two layers using a spectral decomposition algorithm. Two modes:
hpss(default) -- HPSS median-filter harmonic/percussive separationsine-- SineExtraction partial-tracking sinusoidal/residual separation
cargo run --release --example decompose -- input.wav
cargo run --release --example decompose -- --mode sine input.wavOutput (hpss): <input_stem>_harmonic.wav and <input_stem>_percussive.wav.
Output (sine): <input_stem>_sines.wav and <input_stem>_residual.wav.
Morphs two audio files together using spectral interpolation, sweeping linearly from file 1 to file 2. Two modes:
transport(default) -- optimal-transport spectral morphingmorph-- NMF-based component morphing
cargo run --release --example transform -- input1.wav input2.wav output.wav
cargo run --release --example transform -- --mode morph input1.wav input2.wav output.wavMeasures EBU R128-style integrated loudness and peak level per frame.
use flucoma_rs::analyzation::Loudness;
let mut analyzer = Loudness::new(1024, 44100.0).unwrap();
let frame = vec![0.0f64; 1024]; // fill with audio samples
let result = analyzer.process_frame(
&frame,
true, // k_weighting
true, // true_peak
);
println!("Loudness: {:.1} dBFS", result.loudness_db);
println!("Peak: {:.1} dBFS", result.peak_db);Converts a magnitude spectrum into mel-scaled band energies.
use flucoma_rs::{analyzation::MelBands, fourier::{Stft, WindowType}};
let fft_size = 1024;
let n_bins = fft_size / 2 + 1;
let n_bands = 40;
let mut stft = Stft::new(fft_size, fft_size, fft_size / 2, WindowType::Hann).unwrap();
let mut mel = MelBands::new(n_bands, n_bins, 80.0, 8000.0, 44100.0, fft_size).unwrap();
let frame = vec![0.0f64; fft_size]; // fill with audio samples
let spectrum = stft.process_frame(&frame);
let magnitudes = spectrum.magnitudes();
let bands = mel.process_frame(
&magnitudes,
false, // mag_norm
false, // use_power
false, // log_output
);
println!("Mel bands: {:?}", &bands[..4]);Computes a scalar onset detection value per frame using one of ten spectral difference functions.
use flucoma_rs::analyzation::{Onset, OnsetFunction};
let window_size = 1024;
let filter_size = 5;
let mut odf = Onset::new(window_size, window_size, filter_size).unwrap();
// Feed silent frame to seed history
let silence = vec![0.0f64; window_size];
let frame_delta = 0;
let _ = odf.process_frame(
&silence, OnsetFunction::PowerSpectrum, filter_size, frame_delta);
// Then feed a frame with audio
let mut audio_frame = vec![0.0f64; window_size];
audio_frame[512] = 1.0;
let value = odf.process_frame(
&audio_frame, OnsetFunction::PowerSpectrum, filter_size, 0);
println!("Onset value: {:.4}", value);Enable the ndarray feature to pass ndarray::Array2<f64> directly to the flucoma data algorithms, and to convert returned Matrix values back to ndarray::Array2.
Note: Arrays must be in standard (row-major) layout and must point to continous data.
Via ndarray you can mix and match the existing flucoma algorithms with the ndarray-ecosystem.
flucoma-rs is licensed under the BSD-3-Clause license, consistent with the upstream flucoma-core library.