Ran into issue getting AEC to work with 2 way tcp
Posted: Thu Nov 30, 2023 10:42 am
Managed to get 2 way tcp to work, with i2s stream but attempting to get it to work with AEC ran into issues as echo is not canceled.
Micro-controller: ESP32-S3
Codec: es8388
ESP-ADF Version: v2.6
ESP-IDF Version: v4.4.6
#Note: Mic volume and speaker volume needs to be as loud as possible
Micro-controller: ESP32-S3
Codec: es8388
ESP-ADF Version: v2.6
ESP-IDF Version: v4.4.6
#Note: Mic volume and speaker volume needs to be as loud as possible
Code: Select all
//Pipeline configuration is as follows
//-----------------------------------------------------------------------------------------
// Audio Playback pipeline
//-----------------------------------------------------------------------------------------
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
player = audio_pipeline_init(&pipeline_cfg);
mem_assert(player);
AUDIO_NULL_CHECK(TAG, player, return ESP_FAIL);
ESP_LOGI(TAG, "----> Player_pipeline_open Start <----");
ESP_LOGI(TAG, "Create tcp client stream to read data");
tcp_stream_cfg_t tcp_cfg = TCP_STREAM_CFG_DEFAULT();
tcp_cfg.type = AUDIO_STREAM_READER;
tcp_cfg.port = CONFIG_PLAYBACK_TCP_PORT;
tcp_cfg.host = CONFIG_PLAYBACK_TCP_URL;
tcp_cfg.timeout_ms = 3600 * 1000;
tcp_cfg.task_stack = (16 * 1024);
tcp_cfg.ext_stack = true;
tcp_cfg.task_core = 0;
tcp_cfg.event_handler = tcp_read_stream_event_handle;
tcp_cfg.event_ctx = (void *) &AdsT;
tcp_stream_reader = tcp_stream_init(&tcp_cfg);
AUDIO_NULL_CHECK(TAG, tcp_stream_reader, return 0);
rsp_filter_cfg_t rsp_cfg_w = DEFAULT_RESAMPLE_FILTER_CONFIG();
rsp_cfg_w.src_rate = 16000;
rsp_cfg_w.src_ch = 1;
rsp_cfg_w.dest_rate = 16000;
rsp_cfg_w.dest_ch = 1;
rsp_cfg_w.task_stack = (16 * 1024);
rsp_cfg_w.out_rb_size = (4 * 1024);
rsp_cfg_w.stack_in_ext = true;
rsp_cfg_w.task_core = 0;
rsp_cfg_w.complexity = 5;
filter_w = rsp_filter_init(&rsp_cfg_w);
AUDIO_NULL_CHECK(TAG, filter_w, return 0);
audio_element_set_write_cb(filter_w, i2s_write_cb, NULL);
audio_element_set_output_timeout(filter_w, portMAX_DELAY);
ESP_LOGI(TAG, "Create i2s stream to write data to codec chip");
ESP_LOGI(TAG, "Register all elements to audio player pipeline");
audio_pipeline_register(player, tcp_stream_reader, "TCP_RD");
audio_pipeline_register(player, filter_w, "filter_w");
ESP_LOGI(TAG, "Link it together TCP_WR-->filter-->[codec_chip]");
const char *link_tag[2] = {"TCP_RD", "filter_w"};
audio_pipeline_link(player, &link_tag[0], 2);
ESP_LOGI(TAG, "VOIP player has been created");
ESP_LOGI(TAG, "----> Player_pipeline_open End <----");
//-----------------------------------------------------------------------------------------
// Audio Record pipeline
//-----------------------------------------------------------------------------------------
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
recorder = audio_pipeline_init(&pipeline_cfg);
mem_assert(recorder);
AUDIO_NULL_CHECK(TAG, recorder, return ESP_FAIL);
ESP_LOGI(TAG, " ----> Recorder_pipeline_open Start <----");
ESP_LOGI(TAG, "Create algorithm stream for aec");
algorithm_stream_cfg_t algo_config = ALGORITHM_STREAM_CFG_DEFAULT();
algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE2;
algo_config.sample_rate = I2S_SAMPLE_RATE;
algo_config.task_core = 1;
algo_config.stack_in_ext = 1;
algo_config.task_prio = 22;
algo_config.algo_mask = (ALGORITHM_STREAM_USE_AEC|ALGORITHM_STREAM_USE_AGC|ALGORITHM_STREAM_USE_NS);
algo_config.rec_linear_factor = 1;
algo_config.ref_linear_factor = 1;
algo_config.agc_gain = 20;
algo_config.task_stack = (16 * 1024);
algo_config.out_rb_size = (8 * 1024);
element_algo = algo_stream_init(&algo_config);
AUDIO_NULL_CHECK(TAG, element_algo, return 0);
audio_element_set_music_info(element_algo, I2S_SAMPLE_RATE, I2S_CHANNELS, I2S_BITS);
audio_element_set_read_cb(element_algo, i2s_read_cb, NULL);
audio_element_set_input_timeout(element_algo, portMAX_DELAY);
ESP_LOGI(TAG, "Create tcp client stream to write data");
tcp_stream_cfg_t tcp_cfg = TCP_STREAM_CFG_DEFAULT();
tcp_cfg.type = AUDIO_STREAM_WRITER;
tcp_cfg.port = CONFIG_PLAYBACK_TCP_PORT;
tcp_cfg.host = CONFIG_RECORD_TCP_URL;
tcp_cfg.task_core = 1;
tcp_cfg.task_prio = 15;
tcp_cfg.timeout_ms = 3600 * 1000;
tcp_cfg.task_stack = (16 * 1024);
tcp_cfg.event_handler = tcp_write_stream_event_handle;
tcp_cfg.event_ctx = (void *) &AdsT;
tcp_stream_writer = tcp_stream_init(&tcp_cfg);
AUDIO_NULL_CHECK(TAG, tcp_stream_writer, return 0);
ESP_LOGI(TAG, "Register all elements to audio recorder pipeline");
audio_pipeline_register(recorder, element_algo, "algo");
audio_pipeline_register(recorder, tcp_stream_writer, "TCP_WR");
ESP_LOGI(TAG, "Link it together Algo-->TCP_WR");
const char *link_tag[2] = {"algo","TCP_WR"};
audio_pipeline_link(recorder, &link_tag[0], 2);
ESP_LOGI(TAG, "VOIP recorder has been created");
ESP_LOGI(TAG, " ----> Recorder_pipeline_open End <----");
//Please reference the way of ALGORITHM_STREAM_INPUT_TYPE2 in "algorithm_stream.h"
ringbuf_ref = rb_create(256, 1);
audio_element_set_multi_input_ringbuf(element_algo, ringbuf_ref, 0);
/* When the playback signal far ahead of the recording signal,
the playback signal needs to be delayed */
algo_stream_set_delay(element_algo, ringbuf_ref, 5);
//-----------------------------------------------------------------------------------------
// Codec Config
//-----------------------------------------------------------------------------------------
audio_hal_set_volume(board_handle->audio_hal, 95);
es8388_set_mic_gain(24);
//-----------------------------------------------------------------------------------------
// I2s driver Config
//-----------------------------------------------------------------------------------------
i2s_config_t i2s_cfg = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX,
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = bits,
.channel_format = channels,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
.dma_buf_count = 8,
.dma_buf_len = 300,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = 0
};