Add more.

This commit is contained in:
Colin 2025-12-22 22:54:26 +08:00
parent 646b29790e
commit 51b1edb9e6
6 changed files with 203 additions and 35 deletions

View File

@ -16,6 +16,7 @@
"vector": "c",
"unordered_map": "c",
"esp_netif_sntp.h": "c",
"sdmmc_cmd.h": "c"
"sdmmc_cmd.h": "c",
"app_ui.h": "c"
}
}

View File

@ -13,6 +13,7 @@
#include "esp_process_sdkconfig.h"
#include "esp_wn_iface.h"
#include "esp_wn_models.h"
#include "format_wav.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "model_path.h"
@ -26,6 +27,70 @@ static esp_afe_sr_data_t* afe_data = NULL;
int detect_flag = 0;
static volatile int task_flag = 0;
FILE* f1;
FILE* f2;
size_t wav_written1;
size_t wav_written2;
esp_err_t record_start() {
esp_err_t ret = ESP_OK;
const wav_header_t wav_header1 =
WAV_HEADER_PCM_DEFAULT(16000 * 2 * 16 / 8 * 20, 16, 16000, 2);
const wav_header_t wav_header2 =
WAV_HEADER_PCM_DEFAULT(16000 * 1 * 16 / 8 * 20, 16, 16000, 1);
ESP_LOGI(TAG, "Opening file %s", "/sdcard/aaaaa.wav");
f1 = fopen("/sdcard/aaaaa.wav", "w");
ESP_RETURN_ON_FALSE(f1, ESP_FAIL, TAG, "error while opening wav file");
ESP_RETURN_ON_FALSE(fwrite(&wav_header1, sizeof(wav_header_t), 1, f1),
ESP_FAIL, TAG, "error while writing wav header");
f2 = fopen("/sdcard/bbbbb.wav", "w");
ESP_RETURN_ON_FALSE(f2, ESP_FAIL, TAG, "error while opening wav file");
ESP_RETURN_ON_FALSE(fwrite(&wav_header2, sizeof(wav_header_t), 1, f2),
ESP_FAIL, TAG, "error while writing wav header");
wav_written1 = 0;
wav_written2 = 0;
return ESP_OK;
}
esp_err_t record_add1(int16_t* data1, uint32_t size) {
uint32_t byte_rate = 16000 * 2 * 16 / 8;
uint32_t wav_size = byte_rate * 20;
if (wav_written1 < wav_size) {
ESP_RETURN_ON_FALSE(fwrite(data1, size, 1, f1), ESP_FAIL, TAG,
"error while writing samples to wav file");
wav_written1 += size;
return ESP_OK;
} else {
if (wav_written1 < 0xFFFFFFFF) {
ESP_LOGI(TAG, "Recording done 1! Flushing file buffer");
fclose(f1);
wav_written1 = 0xFFFFFFFF;
}
}
return ESP_OK;
}
esp_err_t record_add2(int16_t* data2, uint32_t size) {
uint32_t byte_rate = 16000 * 1 * 16 / 8;
uint32_t wav_size = byte_rate * 20;
if (wav_written2 < wav_size) {
ESP_RETURN_ON_FALSE(fwrite(data2, size, 1, f2), ESP_FAIL, TAG,
"error while writing samples to wav file");
wav_written2 += size;
return ESP_OK;
} else {
if (wav_written2 < 0xFFFFFFFF) {
ESP_LOGI(TAG, "Recording done 2! Flushing file buffer");
fclose(f2);
wav_written2 = 0xFFFFFFFF;
}
}
return ESP_OK;
}
void feed_Task(void* arg) {
esp_afe_sr_data_t* afe_data = arg; // 获取参数
int audio_chunksize = afe_handle->get_feed_chunksize(afe_data); // 获取帧长度
@ -37,10 +102,15 @@ void feed_Task(void* arg) {
MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); // 分配获取I2S数据的缓存大小
assert(i2s_buff);
printf("AFE audio_chunksize : %d\n", audio_chunksize);
printf("AFE nch: %d\n", nch);
printf("AFE feed_channel: %d\n", feed_channel);
while (task_flag) {
bsp_get_feed_data(
false, i2s_buff,
audio_chunksize * sizeof(int16_t) * feed_channel); // 获取I2S数据
record_add1(i2s_buff, audio_chunksize * sizeof(int16_t) * 2);
afe_handle->feed(afe_data, i2s_buff); // 把获取到的I2S数据输入给afe_data
}
@ -80,6 +150,37 @@ void detect_Task(void* arg) {
while (task_flag) {
afe_fetch_result_t* res = afe_handle->fetch(afe_data); // 获取模型输出结果
record_add2(res->data, res->data_size);
// int16_t *data; // the data of audio.
// int data_size; // the size of data. The unit is
// byte. float data_volume; // the volume of input
// audio, the unit is decibel(dB). This value is calculated before agc.
// (note: invalid in vc).
// // if enable wakenet, the window
// length is the receptive fields of
// wakenet(about 1.5s), otherwise is
// the frame length.
// wakenet_state_t wakeup_state; // the value is wakenet_state_t
// int wake_word_index; // if the wake word is detected.
// It will store the wake word index which start from 1. int
// wakenet_model_index; // if there are multiple wakenets,
// this value identifies which model be wakes up. Index start from 1.
// afe_vad_state_t vad_state; // the value is afe_vad_state_t
// int trigger_channel_id; // the channel index of output
// int wake_word_length; // the length of wake word. It's
// unit is the number of samples. int ret_value; //
// the return state of fetch function void* reserved; // reserved for future
// use
if (res->vad_state > 0) {
printf("AFE data_size: %d\n", res->data_size);
printf("AFE data_volume: %f\n", res->data_volume);
printf("AFE vad_state: %d\n", res->vad_state);
printf("AFE ret_value: %d\n", res->ret_value);
}
if (!res || res->ret_value == ESP_FAIL) {
printf("fetch error!\n");
break;
@ -160,23 +261,55 @@ void detect_Task(void* arg) {
}
void app_sr_init(void) {
models = esp_srmodel_init(
"model"); // 获取模型 名称“model”和分区表中装载模型的名称一致
// 获取模型 名称“model”和分区表中装载模型的名称一致
models = esp_srmodel_init("model");
afe_handle =
(esp_afe_sr_iface_t*)&ESP_AFE_SR_HANDLE; // 先配置afe句柄
// 随后才可以调用afe接口
afe_handle = (esp_afe_sr_iface_t*)&ESP_AFE_SR_HANDLE;
// 先配置afe句柄
// 随后才可以调用afe接口
afe_config_t afe_config = AFE_CONFIG_DEFAULT(); // 配置afe
// 配置唤醒模型 必须在create_from_config之前配置
afe_config.wakenet_model_name = esp_srmodel_filter(
models, ESP_WN_PREFIX,
NULL); // 配置唤醒模型 必须在create_from_config之前配置
afe_data = afe_handle->create_from_config(&afe_config); // 创建afe_data
ESP_LOGI(TAG, "wakenet:%s", afe_config.wakenet_model_name); // 打印唤醒名称
afe_config.aec_init = true;
afe_config.se_init = true;
afe_config.vad_init = true;
afe_config.wakenet_init = false;
afe_config.voice_communication_init = false;
afe_config.voice_communication_agc_init = true;
afe_config.voice_communication_agc_gain = 15;
afe_config.vad_mode = VAD_MODE_3;
afe_config.wakenet_model_name = NULL;
afe_config.wakenet_model_name_2 = NULL;
afe_config.wakenet_mode = DET_MODE_2CH_90;
afe_config.afe_mode = SR_MODE_LOW_COST;
afe_config.afe_perferred_core = 0;
afe_config.afe_perferred_priority = 5;
afe_config.afe_ringbuf_size = 50;
afe_config.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM;
afe_config.afe_linear_gain = 4.0;
afe_config.agc_mode = AFE_MN_PEAK_AGC_MODE_2;
afe_config.pcm_config.total_ch_num = 3;
afe_config.pcm_config.mic_num = 2;
afe_config.pcm_config.ref_num = 1;
afe_config.pcm_config.sample_rate = 16000;
afe_config.debug_init = false;
// afe_config.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL},
// {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}};
afe_config.afe_ns_mode = NS_MODE_SSP;
afe_config.afe_ns_model_name = NULL;
// afe_config.wakenet_model_name =
// esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
afe_data = afe_handle->create_from_config(&afe_config); // 创建afe_data
// ESP_LOGI(TAG, "wakenet:%s", afe_config.wakenet_model_name); //
// 打印唤醒名称
task_flag = 1;
// xTaskCreatePinnedToCore(&detect_Task, "detect", 8 * 1024, (void*)afe_data, 5,
// NULL, 1);
// xTaskCreatePinnedToCore(&feed_Task, "feed", 8 * 1024, (void*)afe_data, 5,
// NULL, 0);
record_start();
xTaskCreatePinnedToCore(&detect_Task, "detect", 8 * 1024, (void*)afe_data, 5,
NULL, 1);
xTaskCreatePinnedToCore(&feed_Task, "feed", 8 * 1024, (void*)afe_data, 5,
NULL, 0);
}

View File

@ -252,7 +252,7 @@ esp_err_t bsp_spiffs_mount(void);
#define CODEC_DEFAULT_SAMPLE_RATE (16000)
#define CODEC_DEFAULT_BIT_WIDTH (32)
#define CODEC_DEFAULT_ADC_VOLUME (24.0)
#define CODEC_DEFAULT_ADC_VOLUME (90.0)
#define CODEC_DEFAULT_CHANNEL (2)
#define BSP_I2S_NUM I2S_NUM_1

View File

@ -8,7 +8,7 @@ dependencies:
chmorgan/esp-audio-player: "~1.0.7" # 音频播放
chmorgan/esp-file-iterator: "1.0.0" # 获取文件
espressif/esp_codec_dev: "~1.3.0" # 音频驱动
espressif/esp-sr: "~1.6.0" # 语音识别
espressif/esp-sr: "^1.6.0" # 语音识别
idf:
version: ">=5.4.0"

View File

@ -304,35 +304,33 @@ void app_main(void) {
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
sdmmc_card_t* sdmmc_card = mount_sdcard();
bsp_i2c_init(); // I2C初始化
// pca9557_init(); // IO扩展芯片初始化
// bsp_lvgl_start(); // 初始化液晶屏lvgl接口
bsp_spiffs_mount(); // SPIFFS文件系统初始化
// bsp_codec_init(); // 音频初始化
bsp_codec_init(); // 音频初始化
// mp3_player_init(); // MP3播放器初始化
app_sr_init(); // 语音识别初始化
/* 初始化I2S接口 */
i2s_chan_handle_t i2s_rx_chan = es7210_i2s_init();
es7210_codec_init();
wifi_connect();
record_file_name = malloc(64);
sdmmc_card_t* sdmmc_card = mount_sdcard();
// i2s_chan_handle_t i2s_rx_chan = es7210_i2s_init();
// es7210_codec_init();
// wifi_connect();
// record_file_name = malloc(64);
// while (1) {
// esp_err_t err = record_wav(i2s_rx_chan);
// if (err == ESP_OK) {
// ESP_LOGI(TAG, "Audio success recorded into %s.", record_file_name);
// } else {
// ESP_LOGE(TAG, "Record failed, %s .", record_file_name);
// }
// }
// esp_vfs_fat_sdcard_unmount(SD_MOUNT_POINT, sdmmc_card);
while (1) {
esp_err_t err = record_wav(i2s_rx_chan);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Audio was successfully recorded into %s.",
record_file_name);
} else {
ESP_LOGE(TAG, "Record failed, %s .", record_file_name);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
esp_vfs_fat_sdcard_unmount(SD_MOUNT_POINT, sdmmc_card);
}

View File

@ -24,3 +24,39 @@ CONFIG_LV_FONT_MONTSERRAT_24=y
CONFIG_LV_FONT_MONTSERRAT_32=y
CONFIG_LV_USE_GIF=y
CONFIG_CODEC_I2C_BACKWARD_COMPATIBLE=y
#
# ESP Speech Recognition
#
CONFIG_MODEL_IN_FLASH=y
# CONFIG_MODEL_IN_SDCARD is not set
CONFIG_USE_AFE=y
CONFIG_AFE_INTERFACE_V1=y
# CONFIG_USE_NSNET is not set
CONFIG_USE_WAKENET=y
# CONFIG_SR_WN_WN8_ALEXA is not set
CONFIG_SR_WN_WN9_HILEXIN=y
# CONFIG_SR_WN_WN9_XIAOAITONGXUE is not set
# CONFIG_SR_WN_WN9_ALEXA is not set
# CONFIG_SR_WN_WN9_HIESP is not set
# CONFIG_SR_WN_WN9_HIMFIVE is not set
# CONFIG_SR_WN_WN9_NIHAOXIAOZHI is not set
# CONFIG_SR_WN_WN9_JARVIS_TTS is not set
# CONFIG_SR_WN_WN9_COMPUTER_TTS is not set
# CONFIG_SR_WN_WN9_HEYWILLOW_TTS is not set
# CONFIG_SR_WN_WN9_CUSTOMWORD is not set
# CONFIG_SR_WN_LOAD_MULIT_WORD is not set
CONFIG_USE_MULTINET=y
# CONFIG_SR_MN_CN_NONE is not set
# CONFIG_SR_MN_CN_MULTINET5_RECOGNITION_QUANT8 is not set
CONFIG_SR_MN_CN_MULTINET6_QUANT=y
# CONFIG_SR_MN_CN_MULTINET6_AC_QUANT is not set
# CONFIG_SR_MN_CN_MULTINET7_QUANT is not set
# CONFIG_SR_MN_CN_MULTINET7_AC_QUANT is not set
CONFIG_SR_MN_EN_NONE=y
# CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION_QUANT8 is not set
# CONFIG_SR_MN_EN_MULTINET6_QUANT is not set
# CONFIG_SR_MN_EN_MULTINET7_QUANT is not set
# end of ESP Speech Recognition