Open
Description
Hey
I'm trying to use this library for echo cancellation like this example in aec-rs crate:
https://github.com/thewh1teagle/aec-rs/blob/main/examples/wav.rs
But I don't understand how to use it that way.
I tried the following but it doesn't cancel the echo
/*
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/rec.wav
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/echo.wav
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/voice.wav
cargo run --example wav rec.wav echo.wav cancelled.wav
*/
use hound;
use webrtc_audio_processing::*;
const SAMPLE_RATE: f64 = 16_000.0; // 16kHz
const FRAMES_PER_BUFFER: u32 = 480; // 10ms per buffer
fn create_processor() -> Result<Processor, Box<dyn std::error::Error>> {
let mut processor = Processor::new(&InitializationConfig {
num_capture_channels: 1,
num_render_channels: 1,
..InitializationConfig::default()
})?;
let config = Config {
echo_cancellation: Some(EchoCancellation {
suppression_level: EchoCancellationSuppressionLevel::High,
stream_delay_ms: Some(0),
enable_delay_agnostic: false,
enable_extended_filter: false,
}),
enable_high_pass_filter: false,
..Config::default()
};
processor.set_config(config);
Ok(processor)
}
fn main() {
let rec_path = std::env::args().nth(1).expect("Please specify echo path");
let echo_path = std::env::args().nth(2).expect("Please specify rec path");
let out_path = std::env::args().nth(3).expect("Please specify out path");
// Read echo samples
let mut reader = hound::WavReader::open(echo_path).unwrap();
let echo_samples: Vec<f32> = reader.samples::<i16>()
.map(|s| s.unwrap() as f32 / i16::MAX as f32) // Convert i16 to f32 (normalize)
.collect();
// Read recorded samples
let mut reader = hound::WavReader::open(rec_path).unwrap();
let rec_samples: Vec<f32> = reader.samples::<i16>()
.map(|s| s.unwrap() as f32 / i16::MAX as f32) // Convert i16 to f32 (normalize)
.collect();
let mut processor = create_processor().unwrap();
let frame_size = FRAMES_PER_BUFFER as usize;
// Prepare output WAV writer
let spec = hound::WavSpec {
channels: 1,
sample_rate: SAMPLE_RATE as u32,
bits_per_sample: 16,
sample_format: hound::SampleFormat::Int,
};
let mut writer = hound::WavWriter::create(&out_path, spec).unwrap();
let mut output_samples = Vec::new();
let mut input_frame = vec![0f32; frame_size];
let mut reference_frame = vec![0f32; frame_size];
// Process samples frame by frame
for i in (0..rec_samples.len()).step_by(frame_size) {
let end = usize::min(i + frame_size, rec_samples.len());
// Fill frames with input and reference samples
input_frame[..end - i].copy_from_slice(&rec_samples[i..end]);
reference_frame[..end - i].copy_from_slice(&echo_samples[i..end]);
// Apply echo cancellation using webrtc-audio-processing
processor.process_capture_frame(&mut input_frame).unwrap();
processor.process_render_frame(&mut reference_frame).unwrap();
// Convert the output back to i16 and write to the output file
for &sample in &input_frame {
writer.write_sample((sample * i16::MAX as f32) as i16).unwrap();
}
// Add to output_samples
output_samples.extend_from_slice(&input_frame);
}
println!("Created {}", out_path);
}
Metadata
Metadata
Assignees
Labels
No labels