gosuto_libwebrtc/native/
apm.rs1use cxx::UniquePtr;
16use gosuto_webrtc_sys::apm::ffi as sys_apm;
17
18use crate::{RtcError, RtcErrorType};
19
20pub struct AudioProcessingModule {
21 sys_handle: UniquePtr<sys_apm::AudioProcessingModule>,
22}
23
24impl AudioProcessingModule {
25 pub fn new(
26 echo_canceller_enabled: bool,
27 gain_controller_enabled: bool,
28 high_pass_filter_enabled: bool,
29 noise_suppression_enabled: bool,
30 ) -> Self {
31 Self {
32 sys_handle: unsafe {
33 sys_apm::create_apm(
34 echo_canceller_enabled,
35 gain_controller_enabled,
36 high_pass_filter_enabled,
37 noise_suppression_enabled,
38 )
39 },
40 }
41 }
42
43 pub fn process_stream(
44 &mut self,
45 data: &mut [i16],
46 sample_rate: i32,
47 num_channels: i32,
48 ) -> Result<(), RtcError> {
49 let samples_per_10ms = (sample_rate as usize / 100) * num_channels as usize;
50 assert!(
51 data.len() % samples_per_10ms == 0 && data.len() >= samples_per_10ms,
52 "slice must have a multiple of 10ms worth of samples"
53 );
54
55 for chunk in data.chunks_mut(samples_per_10ms) {
56 if unsafe {
57 self.sys_handle.pin_mut().process_stream(
58 chunk.as_mut_ptr(),
59 chunk.len(),
60 chunk.as_mut_ptr(),
61 chunk.len(),
62 sample_rate,
63 num_channels,
64 )
65 } != 0
66 {
67 return Err(RtcError {
68 error_type: RtcErrorType::Internal,
69 message: "Failed to process stream".to_string(),
70 });
71 }
72 }
73
74 Ok(())
75 }
76
77 pub fn process_reverse_stream(
78 &mut self,
79 data: &mut [i16],
80 sample_rate: i32,
81 num_channels: i32,
82 ) -> Result<(), RtcError> {
83 let samples_per_10ms = (sample_rate as usize / 100) * num_channels as usize;
84 assert!(
85 data.len() % samples_per_10ms == 0 && data.len() >= samples_per_10ms,
86 "slice must have a multiple of 10ms worth of samples"
87 );
88
89 for chunk in data.chunks_mut(samples_per_10ms) {
90 if unsafe {
91 self.sys_handle.pin_mut().process_reverse_stream(
92 chunk.as_mut_ptr(),
93 chunk.len(),
94 chunk.as_mut_ptr(),
95 chunk.len(),
96 sample_rate,
97 num_channels,
98 )
99 } != 0
100 {
101 return Err(RtcError {
102 error_type: RtcErrorType::Internal,
103 message: "Failed to process reverse stream".to_string(),
104 });
105 }
106 }
107
108 Ok(())
109 }
110
111 pub fn set_stream_delay_ms(&mut self, delay_ms: i32) -> Result<(), RtcError> {
112 if self.sys_handle.pin_mut().set_stream_delay_ms(delay_ms) == 0 {
113 Ok(())
114 } else {
115 Err(RtcError {
116 error_type: RtcErrorType::Internal,
117 message: "Failed to set stream delay".to_string(),
118 })
119 }
120 }
121}