use std::f32::consts::PI;
use timestretch::{EdmPreset, StretchParams};
fn main() {
let sample_rate = 44100u32;
let duration_secs = 2.0;
let num_samples = (duration_secs * sample_rate as f32) as usize;
let mut input = vec![0.0f32; num_samples];
let kick_interval = (0.5 * sample_rate as f32) as usize;
for kick_idx in 0..4 {
let pos = kick_idx * kick_interval;
for i in 0..4000 {
if pos + i < num_samples {
let t = i as f32 / sample_rate as f32;
let freq = 120.0 - 70.0 * (t / 0.1);
let env = (-t * 25.0).exp();
input[pos + i] += 0.8 * env * (2.0 * PI * freq * t).sin();
}
}
}
for hat_idx in 0..8 {
let pos = (hat_idx as f32 * 0.25 * sample_rate as f32) as usize + kick_interval / 2;
for i in 0..500 {
if pos + i < num_samples {
let t = i as f32 / sample_rate as f32;
let env = (-t * 200.0).exp();
let noise = ((i as f32 * 7919.0).sin() * 43_758.547).fract();
input[pos + i] += 0.3 * env * noise;
}
}
}
println!("Halftime Effect Demo");
println!(
"Input: {} samples ({:.2}s at 120 BPM)",
input.len(),
duration_secs
);
let params = StretchParams::new(1.0)
.with_preset(EdmPreset::Halftime)
.with_sample_rate(sample_rate)
.with_channels(1);
let output = timestretch::stretch_to_bpm(&input, 120.0, 60.0, ¶ms).expect("stretch failed");
let output_duration = output.len() as f64 / sample_rate as f64;
let actual_ratio = output.len() as f64 / input.len() as f64;
println!(
"Output: {} samples ({:.2}s at ~60 BPM)",
output.len(),
output_duration
);
println!("Actual ratio: {:.3}", actual_ratio);
let input_rms =
(input.iter().map(|s| (*s as f64).powi(2)).sum::<f64>() / input.len() as f64).sqrt();
let output_rms =
(output.iter().map(|s| (*s as f64).powi(2)).sum::<f64>() / output.len() as f64).sqrt();
println!("Input RMS: {:.4}", input_rms);
println!("Output RMS: {:.4}", output_rms);
}