Which filter should I use for Echo Cancellation? #2096
-
Problem DescriptionHi, Thanks for your lib. It's very useful. I have build a device with one I2S Mic and one I2S speaker with ESP32S3. Based "streams-i2s-i2s" example, it's done quickly. But I found the MIC is very sensitive, there would be echo when I set the speaker load. Which filter should I use for Echo Cancellation? Ziv Device DescriptionSelf made board, core is ESP32-S3 Sketch/**
@file streams-i2s-i2s-2.ino
@brief Copy audio from I2S to I2S: We use 2 different i2s ports!
@author Phil Schatzmann
@copyright GPLv3
*/
#include <Wire.h>
#include "AudioTools.h"
AudioInfo IN_info(16000, 2, 32);
AudioInfo OUT_info(16000, 2, 32);
I2SStream in;
I2SStream out;
StreamCopy copier(out, in); // copies sound into i2s
//FormatConverterStream converter(in); // or use converter(out)
//StreamCopy copier(out, converter); // copier(converter, sound);
// HT513 音量
uint16_t Volume;
// 最小音量
#define LOWESTVOLUME 1
#define TOLENCE 16
#define HT513_ADDR_L 0x6c
/**
@brief ht513写寄存器
@param addr 寄存器地址
@param val 要写的值
@retval None
*/
void HT513_WriteOneByte(uint8_t addr, uint8_t val)
{
Wire.beginTransmission(HT513_ADDR_L);
Wire.write(addr);
Wire.write(val);
int ack = Wire.endTransmission(true);
Serial.print("Ack ");
Serial.println(ack, HEX);
}
/**
@brief ht513读寄存器
@param addr 寄存器地址
@retval 读取到的寄存器值
*/
uint8_t HT513_ReadOneByte(uint8_t addr)
{
uint8_t temp = 0;
Wire.beginTransmission(HT513_ADDR_L);
Wire.write(addr);
Wire.endTransmission(false);
uint8_t bytesReceived = 0;
bytesReceived = Wire.requestFrom(HT513_ADDR_L, (uint8_t)1, true);
if (bytesReceived == 1) {
temp = Wire.read();
}
else {
Serial.println("Read Error ");
}
return temp;
}
// Arduino Setup
void setup(void) {
delay(5000);
// HT513 SD Pin 需要设置为 High
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
analogReadResolution(9);
// Open Serial
Serial.begin(115200);
// change to Warning to improve the quality
//AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
Wire.begin(18, 17);
int nDevices;
byte error, address;
Serial.println("Scanning...");
nDevices = 0;
for ( address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
nDevices++;
}
else if (error == 4) {
Serial.print("Unknow error at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
// 设置 SD 为LOW
HT513_WriteOneByte(0x12, 0b11110000);
// 设置数据格式为 I2S, 32Bits
HT513_WriteOneByte(0x13, 0b00000000);
// 读取音量设置
Volume = analogRead(3);
uint8_t Vol=(Volume,0,511,0x07,0xff);
HT513_WriteOneByte(0x16, Vol);
HT513_WriteOneByte(0x15, Vol);
Serial.println(Volume, HEX);
// 调整声道
HT513_WriteOneByte(0x17, 0b10110000);
Serial.println("++++++++++++++++");
// 设置 SD 为HIGH
HT513_WriteOneByte(0x12, 0b11110100);
uint8_t Value = HT513_ReadOneByte(0x12);
Serial.println(Value, HEX);
Value = HT513_ReadOneByte(0x13);
Serial.println(Value, HEX);
Value = HT513_ReadOneByte(0x16);
Serial.println(Value, HEX);
Value = HT513_ReadOneByte(0x17);
Serial.println(Value, HEX);
// Define Converter
//converter.begin(IN_info, OUT_info);
// start I2S in
Serial.println("starting I2S...");
auto config_in = in.defaultConfig(RX_MODE);
config_in.copyFrom(IN_info);
config_in.i2s_format = I2S_STD_FORMAT;
config_in.is_master = true;
config_in.port_no = 1;
config_in.pin_bck = 37;
config_in.pin_ws = 38;
config_in.pin_data = 36;
// config_in.fixed_mclk = sample_rate * 256
// config_in.pin_mck = 2
in.begin(config_in);
// start I2S out
auto config_out = out.defaultConfig(TX_MODE);
config_out.copyFrom(OUT_info);
config_out.i2s_format = I2S_STD_FORMAT;
config_out.is_master = true;
config_out.port_no = 0;
config_out.pin_bck = 15;
config_out.pin_ws = 6;
config_out.pin_data = 7;
config_out.pin_mck = 16;
out.begin(config_out);
Serial.println("I2S started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy();
if (abs(analogRead(3) - Volume) > TOLENCE) {
// 读取音量设置
Volume = analogRead(3);
// 设置 SD 为LOW
HT513_WriteOneByte(0x12, 0b11110000);
uint8_t Vol=map(Volume,0,511,0x07,0xff);
HT513_WriteOneByte(0x16, Vol);
// 设置 SD 为HIGH
HT513_WriteOneByte(0x12, 0b11110100);
Serial.print(analogRead(3), HEX);
Serial.print(" ");
Serial.print(Volume, HEX);
Serial.print(" ");
Serial.println(Vol, HEX);
}
} Other Steps to ReproduceNo response What is your development environment (incl. core version info)Arduino 2.3.6 I have checked existing issues, discussions and online documentation
|
Beta Was this translation helpful? Give feedback.
Answered by
pschatzmann
Jun 30, 2025
Replies: 1 comment 1 reply
-
I guess your issue is rather audio feed-back than echo. Here is some theoretical advice:
|
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
pschatzmann
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I guess your issue is rather audio feed-back than echo.
Here is some theoretical advice: