pub fn to_mono(samples: &[f32], channels: usize) -> Vec<f32> {
let mut mono = Vec::with_capacity(samples.len() / channels);
for chunk in samples.chunks(channels) {
let sum: f32 = chunk.iter().sum();
mono.push(sum / chunk.len() as f32);
}
mono
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn averages_stereo_frames() {
let stereo = vec![0.5, 0.7, 0.3, 0.9];
let mono = to_mono(&stereo, 2);
assert_eq!(mono, vec![0.6, 0.6]);
}
#[test]
fn handles_single_channel_no_copy_needed() {
let mono_in = vec![0.1, -0.1, 0.2];
let mono_out = to_mono(&mono_in, 1);
assert_eq!(mono_out, mono_in);
}
#[test]
fn ignores_incomplete_final_chunk_gracefully() {
let data = vec![1.0, 3.0, 5.0]; let mono = to_mono(&data, 2);
assert_eq!(mono, vec![2.0, 5.0]);
}
}