1#[cfg(not(any(all(target_os = "windows", target_env = "gnu"), target_os = "freebsd")))]
2mod real_implementation {
3 use anyhow::Context;
4 use libwebrtc::native::apm;
5 use parking_lot::Mutex;
6 use std::sync::Arc;
7
8 use crate::{CHANNEL_COUNT, SAMPLE_RATE};
9
10 #[derive(Clone)]
11 pub struct EchoCanceller(Arc<Mutex<apm::AudioProcessingModule>>);
12
13 impl Default for EchoCanceller {
14 fn default() -> Self {
15 Self(Arc::new(Mutex::new(apm::AudioProcessingModule::new(
16 true, false, false, false,
17 ))))
18 }
19 }
20
21 impl EchoCanceller {
22 pub fn process_reverse_stream(&mut self, buf: &mut [i16]) {
23 self.0
24 .lock()
25 .process_reverse_stream(buf, SAMPLE_RATE.get() as i32, CHANNEL_COUNT.get().into())
26 .expect("Audio input and output threads should not panic");
27 }
28
29 pub fn process_stream(&mut self, buf: &mut [i16]) -> anyhow::Result<()> {
30 self.0
31 .lock()
32 .process_stream(buf, SAMPLE_RATE.get() as i32, CHANNEL_COUNT.get() as i32)
33 .context("livekit audio processor error")
34 }
35 }
36}
37
38#[cfg(any(all(target_os = "windows", target_env = "gnu"), target_os = "freebsd"))]
39mod fake_implementation {
40 #[derive(Clone, Default)]
41 pub struct EchoCanceller;
42
43 impl EchoCanceller {
44 pub fn process_reverse_stream(&mut self, _buf: &mut [i16]) {}
45 pub fn process_stream(&mut self, _buf: &mut [i16]) -> anyhow::Result<()> {
46 Ok(())
47 }
48 }
49}
50
51#[cfg(any(all(target_os = "windows", target_env = "gnu"), target_os = "freebsd"))]
52pub use fake_implementation::EchoCanceller;
53#[cfg(not(any(all(target_os = "windows", target_env = "gnu"), target_os = "freebsd")))]
54pub use real_implementation::EchoCanceller;