Skip to content

Instantly share code, notes, and snippets.

@thewh1teagle
Created December 6, 2024 23:25
Show Gist options
  • Save thewh1teagle/929af1c6b05d5f96ceef01130e758471 to your computer and use it in GitHub Desktop.
Save thewh1teagle/929af1c6b05d5f96ceef01130e758471 to your computer and use it in GitHub Desktop.
Echo cancellation that really works
"""
git clone https://github.com/troyliu0105/pyspeexaec
python3 -m venv venv
source venv/bin/activate
pip install soundfile numpy pybind11
CC=clang++ python setup.py install
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/rec.wav
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/echo.wav
python cancel.py
"""
import pyspeexaec
import soundfile as sf
import numpy as np
# Initialize the Echo Canceller
aec = pyspeexaec.EchoCanceller(
frame_size=160,
filter_length=1600,
sample_rate=16000,
mics=1,
speakers=1,
use_preprocess=True
)
# Paths to the audio files
rec_path = 'rec.wav'
ref_path = 'echo.wav'
# Load audio files with soundfile
rec, rec_sr = sf.read(rec_path, dtype='int16') # Returns a numpy array and the sample rate
ref, ref_sr = sf.read(ref_path, dtype='int16')
# Ensure the sample rates are correct
assert rec_sr == 16000, "Recording sample rate must be 16000 Hz"
assert ref_sr == 16000, "Reference sample rate must be 16000 Hz"
# Process audio frame-by-frame
frame_size = 160
num_frames = len(rec) // frame_size
output_frames = []
for i in range(num_frames):
start = i * frame_size
end = start + frame_size
# Process each frame
processed_frame = aec.process(rec[start:end], ref[start:end])
output_frames.append(processed_frame)
# Concatenate all processed frames
output = np.concatenate(output_frames)
# Write the final output to a file
sf.write('output.wav', output, 16000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment