use cute_dsp::rates::{fill_kaiser_sinc, fill_kaiser_sinc_with_centre, Oversampler2xFIR};
fn main() {
println!("Sample Rate Conversion Example");
println!("=============================");
kaiser_sinc_example();
oversampling_example();
}
fn kaiser_sinc_example() {
println!("\nKaiser-windowed Sinc Filter Example:");
let mut filter = vec![0.0f32; 101];
fill_kaiser_sinc(&mut filter, 0.2, 0.3);
println!("Lowpass filter coefficients (first 10 and middle 5):");
for i in 0..10 {
println!("Coefficient {}: {:.6}", i, filter[i]);
}
println!("...");
for i in 48..53 {
println!("Coefficient {}: {:.6}", i, filter[i]);
}
let mut bandpass_filter = vec![0.0f32; 101];
fill_kaiser_sinc_with_centre(&mut bandpass_filter, 0.25);
println!("\nBandpass filter coefficients (first 10 and middle 5):");
for i in 0..10 {
println!("Coefficient {}: {:.6}", i, bandpass_filter[i]);
}
println!("...");
for i in 48..53 {
println!("Coefficient {}: {:.6}", i, bandpass_filter[i]);
}
println!("\nSimplified frequency response analysis:");
analyze_frequency_response(&filter, "Lowpass");
analyze_frequency_response(&bandpass_filter, "Bandpass");
}
fn analyze_frequency_response(filter: &[f32], name: &str) {
let frequencies = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5];
println!("{} filter response:", name);
for &freq in &frequencies {
let mut response = 0.0;
for (i, &coef) in filter.iter().enumerate() {
let phase = 2.0 * std::f32::consts::PI * freq * i as f32;
response += coef * phase.cos();
}
println!(" At frequency {:.1}: {:.3}", freq, response);
}
}
fn oversampling_example() {
println!("\n2x Oversampling Example:");
let mut oversampler = Oversampler2xFIR::<f32>::new(1, 1024, 32, 0.45);
let mut input = vec![0.0; 100];
for i in 0..input.len() {
input[i] = (i as f32 * 0.1).sin();
}
println!("Original signal (first 10 samples):");
for i in 0..10 {
println!("Sample {}: {:.6}", i, input[i]);
}
let latency = oversampler.latency();
println!("\nOversampler latency: {} samples", latency);
oversampler.reset();
oversampler.up_channel(0, &input, input.len());
let oversampled = oversampler.get_channel_ref(0);
println!("\nOversampled signal (first 20 samples):");
for i in 0..20 {
println!("Sample {}: {:.6}", i, oversampled[i]);
}
let mut output = vec![0.0; input.len()];
let output_len = output.len();
oversampler.down_channel(0, &mut output, output_len);
println!("\nDownsampled signal (first 10 samples):");
for i in 0..10 {
println!("Sample {}: {:.6}", i, output[i]);
}
println!("\nError analysis (accounting for latency):");
let mut max_error: f32 = 0.0;
let mut avg_error = 0.0;
let valid_samples = input.len() - latency;
for i in 0..valid_samples {
let error = (input[i] - output[i + latency]).abs();
max_error = max_error.max(error);
avg_error += error;
}
avg_error /= valid_samples as f32;
println!("Maximum error: {:.6}", max_error);
println!("Average error: {:.6}", avg_error);
}