A high-performance, real-time Acoustic Echo Cancellation library written in C++ for VoIP and teleconferencing applications.
- Real-time Processing: <5ms latency for VoIP scenarios
- Adaptive Filtering: NLMS algorithm with fixed-point optimization
- Double-talk Detection: Robust, coherence- and energy-based detector to freeze adaptation during near-end speech (configurable thresholds and hangover)
- Multi-channel Support: Process interleaved input with up to 8 channels (configurable via
AECConfig::channels). Per-channel NLMS filters and per-channel DTDs are used. - Production Ready: Comprehensive tests, benchmarks, and CI/CD
- Cross-platform: Linux, macOS, Windows support
- Modern C++: C++11 with RAII and Pimpl idiom
- Latency: <5ms end-to-end processing
- Echo Reduction: >25dB ERLE (Echo Return Loss Enhancement)
- CPU Usage: Optimized fixed-point arithmetic for embedded systems
git clone
- CMake >= 3.15
- Conan (dependency manager)
- Ninja (optional, for faster builds)
- Android NDK (for Android builds)
# Ubuntu/Debian
sudo apt-get install build-essential cmake ninja
pip install conan
# macOS
brew install cmake ninja
pip3 install conan
# Windows (vcpkg)
vcpkg install cmake ninja gtest benchmark
pip install conangit clone https://github.com/Kiptoo-Deus/aec-library.git
cd aec-library
conan install . --build=missing
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallelcd build && ctest --output-on-failure
./benchmarks/aec_benchmark
./examples/basic_usage# Configure for iOS (arm64)
cmake -B build-ios \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
-DAEC_SRC="src/aec.cpp;src/fixed_point.cpp;src/nlms_filter.cpp"
cmake --build build-ios --parallel
# The output will be aec.framework (for iOS integration)# Set your NDK path and ABI (e.g. arm64-v8a, armeabi-v7a, x86_64)
export ANDROID_NDK_HOME=/path/to/ndk
cmake -B build-android-arm64 \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21
cmake --build build-android-arm64 --parallel
# Repeat for other ABIs- Copy the produced
.sofiles frombuild-android-*to your Android project'sapp/src/main/jniLibs/<ABI>/. - Use the provided
AecWrapper.javain your Android app. - Load the library in Java:
System.loadLibrary("aec");
#include "aec/aec.hpp" #include
int main() { // Configure AEC aec::AECConfig config; config.sample_rate = 16000; config.frame_size = 256; config.use_fixed_point = true;
auto aec = aec::create_aec(config);
// Process audio frames
std::vector<int16_t> far_end(256);
std::vector<int16_t> near_end(256);
std::vector<int16_t> output(256);
aec->process(far_end.data(), near_end.data(), output.data(), 256);
return 0;
}
aec-library/ ├── include/aec/ # Public headers ├── src/ # Implementation ├── tests/ # Unit tests ├── benchmarks/ # Performance benchmarks ├── examples/ # Usage examples └── scripts/ # Utility scripts
-
aec::AEC: Main echo canceller interface
-
aec::AECConfig: Configuration parameters
-
aec::NLMSFilter: Normalized Least Mean Squares adaptive filter
process(): Real-time audio processing
reset(): Reset filter state
get_latency_ms(): Get current processing latency
get_erle(): Get echo cancellation performance
The library includes a configurable double-talk detector enabled by default. Configure behavior via AECConfig fields:
enable_double_talk_detection(bool)dtd_near_to_far_threshold(float)dtd_coherence_threshold(float)dtd_smoothing_alpha(float)dtd_hangover_frames(uint32_t)dtd_use_frequency(bool): enable frequency-domain DTD using smoothed PSD/CSD coherence (default: true)dtd_freq_bins(uint32_t): how many FFT bins to use for coherence estimation (0 = auto frame_size/2)
The detector uses smoothed near/far energies and a coherence estimate to decide whether to freeze adaptation when near-end speech is present.