| Crates.io | bungee-rs |
| lib.rs | bungee-rs |
| version | 0.1.1 |
| created_at | 2025-09-28 12:19:05.006618+00 |
| updated_at | 2025-09-28 12:19:05.006618+00 |
| description | High level Rust FFI bindings for the Bungee audio time-stretching library |
| homepage | |
| repository | https://github.com/emuell/bungee-rs |
| max_upload_size | |
| id | 1858281 |
| size | 49,678 |
bungee-rs provides safe Rust bindings for the Bungee C++ audio time-stretching and pitch-shifting library.
Note: When building this crate locally, clone the repository with git clone --recurse-submodules <url>. It contains the bungee C++ source code as git submodule.
There are two ways to use bungee-rs:
This is the recommended API for most use cases, such as real-time audio processing.
For a full-blown example, see also examples/stream-file.rs in the repository.
use bungee_rs::{Stretcher, Stream};
fn main() -> Result<(), &'static str> {
// Test setup: For 0.75x speed, output is larger than input.
const SAMPLE_RATE: usize = 44100;
const NUM_CHANNELS: usize = 2;
const STRETCH_FACTOR: f64 = 0.75;
const INPUT_BLOCK_SIZE: usize = 1024;
const OUTPUT_BLOCK_SIZE: f64 = INPUT_BLOCK_SIZE as f64 / STRETCH_FACTOR;
// Create a stereo stretcher stream
let mut stream = Stream::new(SAMPLE_RATE, NUM_CHANNELS, INPUT_BLOCK_SIZE)?;
// Prepare planar input and output buffers.
let input_block =
vec![vec![0.0f32; INPUT_BLOCK_SIZE]; NUM_CHANNELS];
let mut output_block =
vec![vec![0.0f32; OUTPUT_BLOCK_SIZE.ceil() as usize]; NUM_CHANNELS];
// In a real application, you would loop here, reading audio into `input_block`.
// Process one block of audio
let output_frame_count = stream.process(
Some(&input_block),
&mut output_block,
INPUT_BLOCK_SIZE,
OUTPUT_BLOCK_SIZE,
1.0, // No pitch shift
);
// `output_frame_count` now contains the number of valid frames in `output_block`.
Ok(())
}
This API gives you fine-grained control over the stretching process, which is useful for non-linear access or custom processing loops, but requires access to the entire audio input data.
use bungee_rs::{Request, Stretcher, OutputChunk};
fn main() -> Result<(), &'static str> {
// Create a stereo stretcher at 44.1kHz
let mut stretcher = Stretcher::new(44100, 2)?;
// Configure playback parameters
let mut request = Request {
pitch: 1.0, // No pitch shift
speed: 0.75, // 75% playback speed
position: 0.0, // Start at beginning
reset: false,
};
// Preroll to initialize internal state
stretcher.preroll(&mut request);
// A real implementation would have a loop here that continues as long as there
// is audio to process. For this example, we'll just process one grain.
// Get required input samples
let input_chunk = stretcher.specify_grain(&request);
// Provide input audio data (add your implementation here).
// Bungee expects non-interleaved audio. For this example, we'll use silence.
let num_frames = input_chunk.len();
let num_channels = 2;
let mut input_data = vec![0.0f32; num_frames * num_channels];
// The channel stride for non-interleaved data is the number of frames per channel.
stretcher.analyse_grain(&mut input_data, num_frames);
// Get output audio
// The output data is also non-interleaved.
let max_output_frames = 2048;
let mut output_data = vec![0.0f32; max_output_frames * num_channels];
let mut output_chunk = OutputChunk::new(&mut output_data, max_output_frames);
stretcher.synthesise_grain(&mut output_chunk);
// Use the output audio. `output_chunk.frame_count` will have the number of valid frames.
// Advance to next grain for the next iteration of the loop
stretcher.next(&mut request);
Ok(())
}
bungee-rs is licensed under the MPL-2.0 license, consistent with the upstream Bungee C++ library.