use cxx::UniquePtr;
use webrtc_sys::apm::ffi as sys_apm;
use crate::{RtcError, RtcErrorType};
pub struct AudioProcessingModule {
sys_handle: UniquePtr<sys_apm::AudioProcessingModule>,
}
impl AudioProcessingModule {
pub fn new(
echo_canceller_enabled: bool,
gain_controller_enabled: bool,
high_pass_filter_enabled: bool,
noise_suppression_enabled: bool,
) -> Self {
Self {
sys_handle: unsafe {
sys_apm::create_apm(
echo_canceller_enabled,
gain_controller_enabled,
high_pass_filter_enabled,
noise_suppression_enabled,
)
},
}
}
pub fn process_stream(
&mut self,
data: &mut [i16],
sample_rate: i32,
num_channels: i32,
) -> Result<(), RtcError> {
let samples_per_10ms = (sample_rate as usize / 100) * num_channels as usize;
assert!(
data.len() % samples_per_10ms == 0 && data.len() >= samples_per_10ms,
"slice must have a multiple of 10ms worth of samples"
);
for chunk in data.chunks_mut(samples_per_10ms) {
if unsafe {
self.sys_handle.pin_mut().process_stream(
chunk.as_mut_ptr(),
chunk.len(),
chunk.as_mut_ptr(),
chunk.len(),
sample_rate,
num_channels,
)
} != 0
{
return Err(RtcError {
error_type: RtcErrorType::Internal,
message: "Failed to process stream".to_string(),
});
}
}
Ok(())
}
pub fn process_reverse_stream(
&mut self,
data: &mut [i16],
sample_rate: i32,
num_channels: i32,
) -> Result<(), RtcError> {
let samples_per_10ms = (sample_rate as usize / 100) * num_channels as usize;
assert!(
data.len() % samples_per_10ms == 0 && data.len() >= samples_per_10ms,
"slice must have a multiple of 10ms worth of samples"
);
for chunk in data.chunks_mut(samples_per_10ms) {
if unsafe {
self.sys_handle.pin_mut().process_reverse_stream(
chunk.as_mut_ptr(),
chunk.len(),
chunk.as_mut_ptr(),
chunk.len(),
sample_rate,
num_channels,
)
} != 0
{
return Err(RtcError {
error_type: RtcErrorType::Internal,
message: "Failed to process reverse stream".to_string(),
});
}
}
Ok(())
}
pub fn set_stream_delay_ms(&mut self, delay_ms: i32) -> Result<(), RtcError> {
if self.sys_handle.pin_mut().set_stream_delay_ms(delay_ms) == 0 {
Ok(())
} else {
Err(RtcError {
error_type: RtcErrorType::Internal,
message: "Failed to set stream delay".to_string(),
})
}
}
}