Skip to content

Commit ea9d6f4

Browse files
committed
[+] feat: add real-time denoise
1 parent 694cc7a commit ea9d6f4

File tree

10 files changed

+545
-207
lines changed

10 files changed

+545
-207
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use hound::WavReader;
2+
use recorder::{DenoiseError, RealTimeDenoise};
3+
use std::sync::{
4+
Arc,
5+
atomic::{AtomicBool, Ordering},
6+
};
7+
8+
fn main() -> Result<(), Box<dyn std::error::Error>> {
9+
env_logger::init();
10+
log::info!("Starting real-time denoise demo...");
11+
log::info!("Press Ctrl-C to stop demo.");
12+
13+
let stop_sig = Arc::new(AtomicBool::new(false));
14+
let stop_sig_clone = stop_sig.clone();
15+
ctrlc::set_handler(move || {
16+
log::info!("Ctrl-C received, stopping demo...");
17+
stop_sig_clone.store(true, Ordering::Relaxed);
18+
})?;
19+
20+
// Read input file to get audio specification
21+
let reader = WavReader::open("target/input.wav")?;
22+
let spec = reader.spec();
23+
24+
log::info!("Audio format:");
25+
log::info!(" Sample rate: {} Hz", spec.sample_rate);
26+
log::info!(" Channels: {}", spec.channels);
27+
log::info!(" Bits per sample: {}", spec.bits_per_sample);
28+
log::info!(" Sample format: {:?}", spec.sample_format);
29+
30+
// Create real-time denoiser
31+
let model = RealTimeDenoise::model();
32+
let mut denoiser = RealTimeDenoise::new(&model, spec)?;
33+
34+
log::info!("Real-time denoiser created successfully");
35+
36+
// Process audio in chunks to simulate real-time processing
37+
let mut total_processed = 0;
38+
let mut total_output = 0;
39+
40+
// Read samples from input file
41+
let samples: Vec<f32> = match spec.sample_format {
42+
hound::SampleFormat::Float => reader
43+
.into_samples::<f32>()
44+
.collect::<Result<Vec<_>, _>>()?,
45+
hound::SampleFormat::Int => match spec.bits_per_sample {
46+
16 => reader
47+
.into_samples::<i16>()
48+
.map(|s| s.map(|v| v as f32))
49+
.collect::<Result<Vec<_>, _>>()?,
50+
24 | 32 => reader
51+
.into_samples::<i32>()
52+
.map(|s| s.map(|v| v as f32))
53+
.collect::<Result<Vec<_>, _>>()?,
54+
_ => {
55+
return Err(Box::new(DenoiseError::UnsupportedBitDepth(
56+
spec.bits_per_sample,
57+
)));
58+
}
59+
},
60+
};
61+
62+
log::info!("Total samples to process: {}", samples.len());
63+
64+
// Process audio in chunks
65+
let chunk_size = 1024; // Process 1024 samples at a time
66+
let mut processed_samples = Vec::new();
67+
68+
let now = std::time::Instant::now();
69+
70+
for chunk in samples.chunks(chunk_size) {
71+
if stop_sig.load(Ordering::Relaxed) {
72+
log::info!("Stopping demo...");
73+
break;
74+
}
75+
76+
total_processed += chunk.len();
77+
78+
// Process the chunk
79+
if let Some(denoised) = denoiser.process_frame(chunk)? {
80+
total_output += denoised.len();
81+
processed_samples.extend(denoised);
82+
83+
log::debug!(
84+
"Processed: {} samples, Output: {} samples, Buffer: {} samples",
85+
total_processed,
86+
total_output,
87+
denoiser.buffered_samples()
88+
);
89+
} else {
90+
log::debug!(
91+
"Buffered: {} samples (waiting for full frame)",
92+
denoiser.buffered_samples()
93+
);
94+
}
95+
}
96+
97+
// Process any remaining buffered samples
98+
if let Some(remained) = denoiser.flush() {
99+
log::info!("Processing remaining buffered samples: {}", remained.len());
100+
101+
total_output += remained.len();
102+
processed_samples.extend(remained);
103+
}
104+
105+
let elapsed = now.elapsed();
106+
107+
log::info!("Real-time denoising completed!");
108+
log::info!(
109+
"Input samples: {}, Output samples: {}, Buffer remaining: {}",
110+
total_processed,
111+
total_output,
112+
denoiser.buffered_samples()
113+
);
114+
log::info!(
115+
"Processing time: {:.2?}, Throughput: {:.2} samples/sec",
116+
elapsed,
117+
total_processed as f64 / elapsed.as_secs_f64()
118+
);
119+
120+
// Save processed audio to file (optional)
121+
if !processed_samples.is_empty() {
122+
log::info!("Saving processed audio to target/output_real_time.wav...");
123+
124+
let mut writer = hound::WavWriter::create("target/output_real_time.wav", spec)?;
125+
for sample in processed_samples {
126+
writer.write_sample(sample)?;
127+
}
128+
writer.finalize()?;
129+
130+
log::info!("Output file saved: target/output_real_time.wav");
131+
}
132+
133+
Ok(())
134+
}
135+

lib/recorder/src/deniose.rs

Lines changed: 0 additions & 201 deletions
This file was deleted.

0 commit comments

Comments
 (0)