use arrayvec::ArrayVec;
pub fn linear_resample<const N: usize>(input: &[f32], output: &mut ArrayVec<f32, N>) {
let input_len = input.len();
let output_len = output.len();
let scale = (input_len - 1) as f32 / (output_len - 1) as f32;
for i in 0..output_len {
let pos = i as f32 * scale;
let pos_floor = pos.floor() as usize;
let pos_ceil = pos.ceil() as usize;
if pos_ceil >= input_len {
output[i] = input[input_len - 1];
} else if pos_floor == pos_ceil {
output[i] = input[pos_floor];
} else {
let weight = pos - pos_floor as f32;
output[i] = input[pos_floor] * (1.0 - weight) + input[pos_ceil] * weight;
}
}
}
pub fn cubic_interpolation(y0: f32, y1: f32, y2: f32, y3: f32, t: f32) -> f32 {
let a0 = -0.5 * y0 + 1.5 * y1 - 1.5 * y2 + 0.5 * y3;
let a1 = y0 - 2.5 * y1 + 2.0 * y2 - 0.5 * y3;
let a2 = -0.5 * y0 + 0.5 * y2;
let a3 = y1;
a0 * t * t * t + a1 * t * t + a2 * t + a3
}
pub fn cubic_resample<const N: usize>(input: &[f32], output: &mut ArrayVec<f32, N>) {
let input_len = input.len();
let output_len = output.len();
let scale = (input_len - 1) as f32 / (output_len - 1) as f32;
for i in 0..output_len {
let pos = i as f32 * scale;
let pos_floor = pos.floor() as usize;
let y0 = if pos_floor == 0 {
input[pos_floor]
} else {
input[pos_floor - 1]
};
let y1 = input[pos_floor];
let y2 = if pos_floor + 1 < input_len {
input[pos_floor + 1]
} else {
input[input_len - 1]
};
let y3 = if pos_floor + 2 < input_len {
input[pos_floor + 2]
} else {
input[input_len - 1]
};
let t = pos - pos_floor as f32;
output[i] = cubic_interpolation(y0, y1, y2, y3, t);
}
}