espressif / esp-box

The ESP-BOX is a new generation AIoT development platform released by Espressif Systems.
Apache License 2.0
779 stars 182 forks source link

gpt_demo改成8388芯片的问题 (AEGHB-673) #150

Closed welkinchan closed 2 months ago

welkinchan commented 3 months ago

我最近把gpt_demo案例运行到我的es8388音频芯片的板子上, 板子原先是使用es8311芯片的,那时候程序运行都是正常的, 但是板子改成es8388芯片后(板子只有1个麦克风和2个喇叭), 唤醒的成功率非常低,大概30次才能唤醒1次,并且比较随机。 比较奇怪的是,唤醒后,我的语音每次都能准确识别(大概6,7次全都是成功的),并且TTS语音播放也都是很正常的。

现在主要的问题就是唤醒的成功率很低, 我觉得不大可能是收音的问题,因为STT的成功率很高, 所以我想咨询一下, gpt_demo中的唤醒逻辑中,对声音的处理逻辑是怎么样的?

  1. 是不是只支持双麦克风?是不是因为我的板子只有1个麦克风,所以导致很难唤醒?
  2. 我的es8388的驱动是直接将codec组件中的es8311的驱动直接按照lyrat开发板的es8388的驱动改的。是不是sr组件中的降噪处理的逻辑是根绝es8311写的,无法适用于es8388?

由于我刚学习嵌入式,很多都不大懂,因此非常希望能够帮忙解答。

espressif2022 commented 3 months ago

1: 是不是只支持双麦克风?是不是因为我的板子只有1个麦克风,所以导致很难唤醒 这边需要匹配,目前默认是两路 mic,一路参考信号,现有 es7210 采样是两路的,回采信号目前置 0 处理。问题2 同理

音频转换

       for (int  i = audio_chunksize - 1; i >= 0; i--) {
            audio_buffer[i * 3 + 2] = 0;
            audio_buffer[i * 3 + 1] = audio_buffer[i * 2 + 1];
            audio_buffer[i * 3 + 0] = audio_buffer[i * 2 + 0];
        }

默认配置 afe_config_t afe_config = AFE_CONFIG_DEFAULT();, 重点 ref_nummic_num

#define AFE_CONFIG_DEFAULT() { \
    .aec_init = true, \
    .se_init = true, \
    .vad_init = true, \
    .wakenet_init = true, \
    .voice_communication_init = false, \
    .voice_communication_agc_init = false, \
    .voice_communication_agc_gain = 15, \
    .vad_mode = VAD_MODE_3, \
    .wakenet_model_name = NULL, \
    .wakenet_model_name_2 = NULL, \
    .wakenet_mode = DET_MODE_2CH_90, \
    .afe_mode = SR_MODE_LOW_COST, \
    .afe_perferred_core = 0, \
    .afe_perferred_priority = 5, \
    .afe_ringbuf_size = 50, \
    .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
    .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
    .pcm_config.total_ch_num = 3, \
    .pcm_config.mic_num = 2, \
    .pcm_config.ref_num = 1, \
    .pcm_config.sample_rate = 16000, \
    .debug_init = false, \
    .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
}
welkinchan commented 3 months ago

fei

1: 是不是只支持双麦克风?是不是因为我的板子只有1个麦克风,所以导致很难唤醒 这边需要匹配,目前默认是两路 mic,一路参考信号,现有 es7210 采样是两路的,回采信号目前置 0 处理。问题2 同理

音频转换

       for (int  i = audio_chunksize - 1; i >= 0; i--) {
            audio_buffer[i * 3 + 2] = 0;
            audio_buffer[i * 3 + 1] = audio_buffer[i * 2 + 1];
            audio_buffer[i * 3 + 0] = audio_buffer[i * 2 + 0];
        }

默认配置 afe_config_t afe_config = AFE_CONFIG_DEFAULT();, 重点 ref_nummic_num

#define AFE_CONFIG_DEFAULT() { \
    .aec_init = true, \
    .se_init = true, \
    .vad_init = true, \
    .wakenet_init = true, \
    .voice_communication_init = false, \
    .voice_communication_agc_init = false, \

非常感谢解答,但是很抱歉,这个解答我没看懂哈。 我还是重新整理一下我的问题吧。

  1. 我找人帮忙定做了一个板子,板子相当于把esp32-box3的板子中的es7210以及es8311这两个芯片用es8388替换了。目前我的板子上可以安装2个麦克风了。现在,我想在新的这个板子上跑通gpt_demo这个例程序。

  2. 但是新的这个板子的麦克风和喇叭的驱动我其实并不知道怎么写,在我参考了lyrat板子的资料后,我就直接将gpt_demo案例中,gpt_demo\components\espressif__esp-box-3\esp-box-3.c这个文件中的 bsp_audio_codec_speaker_init(void)函数以及bsp_audio_codec_microphone_init(void)函数替换成了 bsp_audio_codec_init(void)函数,

代码如下。 按照我的理解,这个代码应该是可以使es8388芯片驱动麦克风和喇叭。

  1. 但是,当我在跑gpt_demo这个例程的时候,发现修改后的代码以及板子的运行效果有很大的异常: (1)语音唤醒很难,几乎30-40次都不一定能唤醒一次,只有极端偶然的情况下才会唤醒。 (2)一旦唤醒,语音对话又是正常的,包括STT,以及TTS都可以正常识别声音,并且正常播放服务器返回的的TTS语音。

  2. 我跑别的一个简易的sr例程的时候,发现是可以正常唤醒的,而且唤醒很容易。 但是跑gpt_demo的时候却很难唤醒。

  3. 所以,能否帮我分析一下,我的故障是什么原因导致的?是不是驱动代码有问题还是什么?

================================= 驱动代码:

static esp_codec_dev_handle_t bsp_audio_codec_init(void) { static esp_codec_dev_handle_t codec = NULL; if (codec) { return codec; }

const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf();
if (i2s_data_if == NULL) {
    /* Initilize I2C */
    BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init());
    /* Configure I2S peripheral and Power Amplifier */
    BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL));
    i2s_data_if = bsp_audio_get_codec_itf();
}
assert(i2s_data_if);

audio_codec_i2c_cfg_t i2c_cfg = {
    .port = BSP_I2C_NUM,
    .addr = ES8388_CODEC_DEFAULT_ADDR,
};
const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
BSP_NULL_CHECK(i2c_ctrl_if, NULL);

esp_codec_dev_hw_gain_t gain = {
    .pa_voltage = 5.0,
    .codec_dac_voltage = 3.3,
};

es8388_codec_cfg_t es8388_cfg = {
    .ctrl_if = i2c_ctrl_if,
    .pa_pin = BSP_POWER_AMP_IO,
    .pa_reverted = false,
    .hw_gain = gain,
};
const audio_codec_if_t *es8388_dev = es8388_codec_new(&es8388_cfg);
BSP_NULL_CHECK(es8388_dev, NULL);

esp_codec_dev_cfg_t codec_dev_cfg = {
    .dev_type = ESP_CODEC_DEV_TYPE_IN_OUT,
    .codec_if = es8388_dev,
    .data_if = i2s_data_if,
};
codec = esp_codec_dev_new(&codec_dev_cfg);
BSP_NULL_CHECK(codec, NULL);

return codec;

}

esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) { return bsp_audio_codec_init(); }

esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void) { return bsp_audio_codec_init(); }

// ((((((((((((((((((((((((((( // esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) // { // const audio_codec_data_if_t i2s_data_if = bsp_audio_get_codec_itf(); // if (i2s_data_if == NULL) { // / Initilize I2C / // BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); // / Configure I2S peripheral and Power Amplifier */ // BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL)); // i2s_data_if = bsp_audio_get_codec_itf(); // } // assert(i2s_data_if);

// const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();

// audio_codec_i2c_cfg_t i2c_cfg = { // .port = BSP_I2C_NUM, // .addr = ES8311_CODEC_DEFAULT_ADDR, // }; // const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); // BSP_NULL_CHECK(i2c_ctrl_if, NULL);

// esp_codec_dev_hw_gain_t gain = { // .pa_voltage = 5.0, // .codec_dac_voltage = 3.3, // };

// es8311_codec_cfg_t es8311_cfg = { // .ctrl_if = i2c_ctrl_if, // .gpio_if = gpio_if, // .codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC, // .pa_pin = BSP_POWER_AMP_IO, // .pa_reverted = false, // .master_mode = false, // .use_mclk = true, // .digital_mic = false, // .invert_mclk = false, // .invert_sclk = false, // .hw_gain = gain, // }; // const audio_codec_if_t *es8311_dev = es8311_codec_new(&es8311_cfg); // BSP_NULL_CHECK(es8311_dev, NULL);

// esp_codec_dev_cfg_t codec_dev_cfg = { // .dev_type = ESP_CODEC_DEV_TYPE_OUT, // .codec_if = es8311_dev, // .data_if = i2s_data_if, // }; // return esp_codec_dev_new(&codec_dev_cfg); // }

// esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void) // { // const audio_codec_data_if_t i2s_data_if = bsp_audio_get_codec_itf(); // if (i2s_data_if == NULL) { // / Initilize I2C / // BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); // / Configure I2S peripheral and Power Amplifier */ // BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL)); // i2s_data_if = bsp_audio_get_codec_itf(); // } // assert(i2s_data_if);

// audio_codec_i2c_cfg_t i2c_cfg = { // .port = BSP_I2C_NUM, // .addr = ES7210_CODEC_DEFAULT_ADDR, // }; // const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); // BSP_NULL_CHECK(i2c_ctrl_if, NULL);

// es7210_codec_cfg_t es7210_cfg = { // .ctrl_if = i2c_ctrl_if, // }; // const audio_codec_if_t *es7210_dev = es7210_codec_new(&es7210_cfg); // BSP_NULL_CHECK(es7210_dev, NULL);

// esp_codec_dev_cfg_t codec_es7210_dev_cfg = { // .dev_type = ESP_CODEC_DEV_TYPE_IN, // .codec_if = es7210_dev, // .data_if = i2s_data_if, // }; // return esp_codec_dev_new(&codec_es7210_dev_cfg); // }

// )))))))))))))))))))))))))))

espressif2022 commented 3 months ago

建议你可以先用这个例程 看下录音-> 播放是否正常。

如果其他 SR 例程可以唤醒,chatgpt 的唤醒我觉得应该也是正常的,两者的工作逻辑和配置都是一样的。 上面是指,SR 的 mic 输入是可配置的,如上答复,默认是 1路回采(目前例程都是没做回采,第三路我们在 I2S 录音结束后强制置 0),2路 mic 输入,并不是强制要求 2路。

一般默认配置录音是配置: sample_rate = 16K,ch = 2,bits_per_sample = 16,这边和其他 demo 配置也是一样的。 播放这会自动解析 mp3 头部,会 reset I2S 的配置, 建议你先跑上述例程的录音测试下是否正常。

ESP-Mars commented 3 months ago

Is there any progress on this issue?

ESP-Mars commented 2 months ago

Temporarily closed the issue. Should you have additional questions or concerns, don't hesitate to reopen the issue.