use std::f32::consts::PI;
use timestretch::engine::{Engine, EngineConfig, EngineProfile};
fn main() {
let sample_rate = 44_100u32;
let callback_frames = 256usize;
let source_audio: Vec<f32> = (0..sample_rate as usize * 4)
.map(|i| 0.5 * (2.0 * PI * 220.0 * i as f32 / sample_rate as f32).sin())
.collect();
let handles = Engine::build(EngineConfig {
sample_rate,
channels: 1,
profile: EngineProfile::Keylock,
..EngineConfig::default()
})
.expect("engine builds");
let (controller, mut processor, mut source) =
(handles.controller, handles.processor, handles.source);
source.set_track_position(0);
let mut feed_cursor = 0usize;
let mut out = vec![0.0f32; callback_frames];
let mut rendered = 0usize;
let mut callback_index = 0usize;
while feed_cursor < source_audio.len() {
let t = callback_index as f64 * callback_frames as f64 / sample_rate as f64;
controller.set_tempo_rate(1.0 + 0.06 * (t / 4.0).min(1.0));
while feed_cursor < source_audio.len()
&& source.occupied_frames() < source.demand_hint(callback_frames, 4.0)
{
let end = (feed_cursor + 4_096).min(source_audio.len());
feed_cursor += source.push(&source_audio[feed_cursor..end]);
}
processor.process(&mut out);
rendered += out.len();
callback_index += 1;
}
println!(
"rendered {} frames across {} callbacks (source position {:.0}, underruns {})",
rendered,
callback_index,
controller.source_position(),
controller.underrun_frames()
);
}