Hi,
Hope you are doing good.
These conversation is very useful for me, based on this I have tried to implement LPF to remove noise from audio signal. But still I am getting noise in output with actual audio signal.
esp-idf version = stable release 4.4.1
Dev-Kit =
https://github.com/W00ng/ESP32-S3-HMI-DevKit
My code is as following.(I am a beginner for I2S interface and audio signals)
Code: Select all
[Codebox=c file=Untitled.c]
#define AUDIO_SAMPLE_RATE AUDIO_HAL_16K_SAMPLES
/* i2s_Sample_Rate * T * sizeof(uint8_t)
16bits,Mono,Record_time = T/2(s) */
#define BUF_SIZE (16000 * 20 * sizeof(uint8_t))
#define FRAME_SIZE (1600)
#define SAMPLES_NUM (1024)
static uint32_t audio_index = 0;
static uint32_t audio_total = 0;
static uint8_t *audio_buffer = NULL;
#if 1
int N = SAMPLES_NUM;
// Input test array
__attribute__((aligned(16)))
float d[SAMPLES_NUM];
// output array
__attribute__((aligned(16)))
float y[SAMPLES_NUM];
__attribute__((aligned(16)))
float y_cf[SAMPLES_NUM*2];
#endif
void audio_record_task(void *args)
{
static esp_err_t ret;
static size_t bytes_read = 0;
static size_t bytes_write = 0;
while (1)
{
if (mode == record) {
ESP_LOGI(TAG, "record start");
audio_index = 0;
while ((mode == record) && (audio_index < (BUF_SIZE - FRAME_SIZE)))
{
ret = i2s_read(I2S_NUM_0, audio_buffer + audio_index, FRAME_SIZE, &bytes_read, 100);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s read failed");
abort();
}
audio_index += FRAME_SIZE;
}
if (mode == record) mode = idle;
ESP_LOGI(TAG, "record end");
}
else if (mode == play)
{
ESP_LOGI(TAG, "play start");
ESP_LOGI(TAG, "audio_index = %d", audio_index);
audio_total = audio_index; //recorder length
audio_index = 0;
esp_err_t ret = ESP_OK, ret_hpf = ESP_OK;
float coeffs_lpf[5];
float coeffs_hpf[5];
float w_lpf[5] = {0,0};
// Calculate iir filter coefficients
ret = dsps_biquad_gen_lpf_f32(coeffs_lpf, 0.1, 0.5); // freq=0.1 and qfact=0.5
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Operation error LPF = %i", ret);
return;
}
#if 1
while(audio_index < audio_total)
{
for (int i=audio_index,j=0; (i-audio_index) < SAMPLES_NUM ; i++,j++)
{
//d[j] = ((float)audio_buffer[i]/(float)32768);
d[j] = (float)audio_buffer[i];
}
// Process input signal
ret = dsps_biquad_f32(d, y, N, coeffs_lpf, w_lpf);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Operation error biquad lpf= %i", ret);
return;
}
for (int i=audio_index, j=0 ; (i-audio_index) < SAMPLES_NUM ; i++,j++)
{
y[j] = y[j] * 0.5;
audio_buffer[i] = (int16_t)y[j];
}
audio_index += SAMPLES_NUM;
vTaskDelay((10) / portTICK_PERIOD_MS);
}
#endif
audio_index = 0;
while ((mode == play) && (audio_index < audio_total))
{
ret = i2s_write(I2S_NUM_0, audio_buffer + audio_index, FRAME_SIZE, &bytes_write, 100);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s write failed");
abort();
}
audio_index += FRAME_SIZE;
}
if (mode == play) mode = idle;
ESP_LOGI(TAG, "play end");
}
else
{
vTaskDelay((100) / portTICK_PERIOD_MS);
}
}
vTaskDelete(NULL);
}
void lv_tick_task(void *arg)
{
while(1)
{
vTaskDelay((10) / portTICK_PERIOD_MS);
lv_task_handler();
}
}
void app_main(void)
{
/* Initialize I2C 400KHz */
ESP_ERROR_CHECK(bsp_i2c_init(I2C_NUM_0, 400000));
/* Init TCA9554 */
ESP_ERROR_CHECK(tca9554_init());
ext_io_t io_conf = BSP_EXT_IO_DEFAULT_CONFIG();
ext_io_t io_level = BSP_EXT_IO_DEFAULT_LEVEL();
ESP_ERROR_CHECK(tca9554_set_configuration(io_conf.val));
ESP_ERROR_CHECK(tca9554_write_output_pins(io_level.val));
/* LVGL init */
lv_init(); //内核初始化
lv_port_disp_init(); //接口初始化
lv_port_indev_init(); //输入设备初始化
// lv_port_fs_init(); //文件系统初始化
lv_port_tick_init();
es8311_codec_config(AUDIO_SAMPLE_RATE);
bsp_i2s_init(I2S_NUM_0, 16000); //config channel_format=mono
/* Allocate audio buffer */
audio_buffer = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_SPIRAM);
if (NULL == audio_buffer) {
ESP_LOGE(TAG, "Failed allocate mem for audio buffer.");
return;
}
ESP_LOGI(TAG, "UI init start");
/* Init UI of example */ // ignore it for now
ui_record(); // just to start recording and play recording using display.
ESP_LOGI(TAG, "UI started");
xTaskCreate(lv_tick_task, "lv_tick_task", 4096, NULL, 1, NULL);
xTaskCreate(audio_record_task, "audio_record_task", 4096*5, NULL, 5, NULL);
}
[/Codebox]
Please suggest me some improvements if I am doing anything wrong in LPF implementation. I have tried all the steps mentioned in previous replies and implemented this code so far.
Thanks in advance.