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