-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwav.rs
64 lines (56 loc) · 2.46 KB
/
wav.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
git submodule update --init
wget https://github.com/thewh1teagle/aec/releases/download/audio-files/rec.wav
wget https://github.com/thewh1teagle/aec/releases/download/audio-files/echo.wav
wget https://github.com/thewh1teagle/aec/releases/download/audio-files/voice.wav
cargo run --example wav rec.wav echo.wav output.wav
*/
use aec_rs::Aec;
use hound::{WavReader, WavWriter};
fn main() {
// File paths for input and output
let rec_path = std::env::args().nth(1).expect("Please specify rec path");
let echo_path = std::env::args().nth(2).expect("Please specify echo path");
let out_path = std::env::args().nth(3).expect("Please specify out path");
// Read the WAV files
let mut rec_reader = WavReader::open(rec_path).unwrap();
let mut echo_reader = WavReader::open(echo_path).unwrap();
// Get the WAV file specs (assuming both files have the same spec)
let spec = rec_reader.spec();
let mut out_writer = WavWriter::create(&out_path, spec).unwrap();
let config = aec_rs::AecConfig {
sample_rate: 16000, // 16Khz (1s)
filter_length: 1600, // 0.1s
frame_size: 160, // 0.01s
enable_preprocess: true, // Denoise as well
};
let aec = Aec::new(&config);
// Initialize buffers with the frame size
let mut rec_buffer = vec![0i16; config.frame_size];
let mut echo_buffer = vec![0i16; config.frame_size];
let mut out_buffer = vec![0i16; config.frame_size];
// Read the entire WAV samples into Vec<i16>
let rec_samples: Vec<i16> = rec_reader
.samples::<i16>()
.collect::<Result<_, _>>()
.unwrap();
let echo_samples: Vec<i16> = echo_reader
.samples::<i16>()
.collect::<Result<_, _>>()
.unwrap();
let num_samples = rec_samples.len().min(echo_samples.len());
for i in 0..(num_samples / config.frame_size) {
// Calculate the slice range for the current frame and copy it into the buffers
rec_buffer
.copy_from_slice(&rec_samples[i * config.frame_size..(i + 1) * config.frame_size]);
echo_buffer
.copy_from_slice(&echo_samples[i * config.frame_size..(i + 1) * config.frame_size]);
// Apply echo cancellation
aec.cancel_echo(&mut rec_buffer, &mut echo_buffer, &mut out_buffer);
// Write the processed frame to the output file
for &sample in &out_buffer {
out_writer.write_sample(sample).unwrap();
}
}
println!("Created {}", out_path);
}