active_call/media/
denoiser.rs1use crate::media::{AudioFrame, PcmBuf, Sample, Samples, processor::Processor};
2use anyhow::Result;
3use audio_codec::Resampler;
4use nnnoiseless::DenoiseState;
5
6pub struct NoiseReducer {
7 resampler_target: Resampler,
8 resampler_source: Resampler,
9 denoiser: Box<DenoiseState<'static>>,
10}
11
12impl NoiseReducer {
13 pub fn new(input_sample_rate: usize) -> Self {
14 let resampler48k = Resampler::new(48000, input_sample_rate);
15 let resampler16k = Resampler::new(input_sample_rate, 48000 as usize);
16 let denoiser = DenoiseState::new();
17 Self {
18 resampler_target: resampler48k,
19 resampler_source: resampler16k,
20 denoiser,
21 }
22 }
23}
24unsafe impl Send for NoiseReducer {}
25unsafe impl Sync for NoiseReducer {}
26
27impl Processor for NoiseReducer {
28 fn process_frame(&mut self, frame: &mut AudioFrame) -> Result<()> {
29 if frame.samples.is_empty() {
31 return Ok(());
32 }
33
34 let samples = match &frame.samples {
35 Samples::PCM { samples } => samples,
36 _ => return Ok(()),
37 };
38 let samples = self.resampler_source.resample(samples);
39 let input_size = samples.len();
40
41 let output_padding_size = input_size + DenoiseState::FRAME_SIZE;
42 let mut output_buf = vec![0.0; output_padding_size];
43 let input_f32: Vec<f32> = samples.iter().map(|&s| s.into()).collect();
44
45 let mut offset = 0;
46 let mut buf;
47
48 while offset < input_size {
49 let remaining_size = input_size - offset;
50 let chunk_len = remaining_size.min(DenoiseState::FRAME_SIZE);
51 let end_offset = offset + chunk_len;
52
53 let input_chunk = if chunk_len < DenoiseState::FRAME_SIZE {
54 buf = vec![0.0; DenoiseState::FRAME_SIZE];
55 buf[..chunk_len].copy_from_slice(&input_f32[offset..end_offset]);
56 &buf
57 } else {
58 &input_f32[offset..end_offset]
59 };
60
61 self.denoiser.process_frame(
63 &mut output_buf[offset..offset + DenoiseState::FRAME_SIZE],
64 &input_chunk,
65 );
66
67 offset += chunk_len;
68 }
69
70 let samples = output_buf[..input_size]
71 .iter()
72 .map(|&s| s as Sample)
73 .collect::<PcmBuf>();
74
75 frame.samples = Samples::PCM {
76 samples: self.resampler_target.resample(&samples),
77 };
78
79 Ok(())
80 }
81}