Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion libwebrtc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub mod video_track;
pub mod native {
pub use webrtc_sys::webrtc::ffi::create_random_uuid;

pub use crate::imp::{audio_resampler, frame_cryptor, yuv_helper};
pub use crate::imp::{aec, audio_resampler, frame_cryptor, yuv_helper};
}

#[cfg(target_os = "android")]
Expand Down
51 changes: 51 additions & 0 deletions libwebrtc/src/native/aec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2023 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use cxx::UniquePtr;
use webrtc_sys::aec::ffi as sys_aec;

pub struct Aec {
sys_handle: UniquePtr<sys_aec::Aec>,
sample_rate: i32,
num_channels: i32,
}

impl Aec {
pub fn new(sample_rate: i32, num_channels: i32) -> Self {
Self {
sys_handle: sys_aec::create_aec(sample_rate, num_channels),
sample_rate,
num_channels,
}
}

pub fn cancel_echo(&mut self, capture: &mut [i16], render: &[i16]) {
let required_samples = (self.sample_rate as usize / 100) * self.num_channels as usize;
assert_eq!(
capture.len(),
required_samples,
"Capture slice must have 10ms worth of samples"
);
assert_eq!(render.len(), required_samples, "Render slice must have 10ms worth of samples");

unsafe {
self.sys_handle.pin_mut().cancel_echo(
capture.as_mut_ptr(),
capture.len(),
render.as_ptr(),
render.len(),
);
}
}
}
1 change: 1 addition & 0 deletions libwebrtc/src/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod aec;
#[cfg(target_os = "android")]
pub mod android;
pub mod audio_resampler;
Expand Down
29 changes: 29 additions & 0 deletions livekit-ffi/protocol/audio_frame.proto
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ message RemixAndResampleResponse {
required OwnedAudioFrameBuffer buffer = 1;
}

// AEC


message NewAecRequest {
required uint32 sample_rate = 1;
required uint32 num_channels = 2;
}
message NewAecResponse {
required OwnedAec aec = 1;
}

message CancelEchoRequest {
required uint64 aec_handle = 1;
required uint64 cap_ptr = 2; // *mut i16
required uint32 cap_size = 3; // in bytes
required uint64 rend_ptr = 4; // *const i16
required uint32 rend_size = 5;
}

message CancelEchoResponse {
optional string error = 3;
}

// New resampler using SoX (much better quality)

Expand Down Expand Up @@ -237,6 +259,13 @@ message OwnedAudioResampler {
}


//
// AEC
//

message OwnedAec {
required FfiOwnedHandle handle = 1;
}

//
// Sox AudioResampler
Expand Down
10 changes: 8 additions & 2 deletions livekit-ffi/protocol/ffi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ message FfiRequest {
// Data Channel
SetDataChannelBufferedAmountLowThresholdRequest set_data_channel_buffered_amount_low_threshold = 47;

// NEXT_ID: 49
NewAecRequest new_aec = 49;
CancelEchoRequest cancel_echo = 50;

// NEXT_ID: 51
}
}

Expand Down Expand Up @@ -188,7 +191,10 @@ message FfiResponse {
// Data Channel
SetDataChannelBufferedAmountLowThresholdResponse set_data_channel_buffered_amount_low_threshold = 46;

// NEXT_ID: 48
NewAecResponse new_aec = 48;
CancelEchoResponse cancel_echo = 49;

// NEXT_ID: 50
}
}

Expand Down
Loading