Detect wake word model from index.json (#1211)

* detect wake word model from index.json

* update wait time before entering wifi configure mode
This commit is contained in:
Xiaoxia
2025-09-17 08:31:51 +08:00
committed by GitHub
parent a1e1f73886
commit f418c16b2c
20 changed files with 75 additions and 134 deletions

View File

@@ -4,7 +4,7 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
set(PROJECT_VER "2.0.1")
set(PROJECT_VER "2.0.2")
# Add this line to disable the specific warning
add_compile_options(-Wno-missing-field-initializers)

View File

@@ -45,6 +45,17 @@ list(APPEND SOURCES ${BOARD_COMMON_SOURCES})
list(APPEND INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/boards/common)
idf_build_get_property(build_components BUILD_COMPONENTS)
# Function to find component dynamically by pattern
function(find_component_by_pattern PATTERN COMPONENT_VAR PATH_VAR)
foreach(COMPONENT ${build_components})
if(COMPONENT MATCHES "${PATTERN}")
set(${COMPONENT_VAR} ${COMPONENT} PARENT_SCOPE)
idf_component_get_property(COMPONENT_PATH ${COMPONENT} COMPONENT_DIR)
set(${PATH_VAR} "${COMPONENT_PATH}" PARENT_SCOPE)
break()
endif()
endforeach()
endfunction()
# Set default BUILTIN_TEXT_FONT and BUILTIN_ICON_FONT
set(BUILTIN_TEXT_FONT font_puhui_14_1)
@@ -64,7 +75,7 @@ elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32)
set(BOARD_TYPE "bread-compact-esp32")
elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32_LCD)
set(BOARD_TYPE "bread-compact-esp32-lcd")
set(BUILTIN_TEXT_FONT font_puhui_14_1)
set(BUILTIN_TEXT_FONT font_puhui_basic_14_1)
set(BUILTIN_ICON_FONT font_awesome_14_1)
elseif(CONFIG_BOARD_TYPE_DF_K10)
set(BOARD_TYPE "df-k10")
@@ -202,14 +213,10 @@ elseif(CONFIG_BOARD_TYPE_ECHOEAR)
set(BUILTIN_TEXT_FONT font_puhui_20_4)
set(BUILTIN_ICON_FONT font_awesome_20_4)
# Find esp_emote_gfx component for ECHOEAR extra files
foreach(COMPONENT ${build_components})
if(COMPONENT MATCHES "esp_emote_gfx" OR COMPONENT MATCHES "espressif2022__esp_emote_gfx")
set(EMOTE_GFX_COMPONENT ${COMPONENT})
idf_component_get_property(EMOTE_GFX_COMPONENT_PATH ${EMOTE_GFX_COMPONENT} COMPONENT_DIR)
set(DEFAULT_ASSETS_EXTRA_FILES "${EMOTE_GFX_COMPONENT_PATH}/emoji_normal")
break()
endif()
endforeach()
find_component_by_pattern("esp_emote_gfx" EMOTE_GFX_COMPONENT EMOTE_GFX_COMPONENT_PATH)
if(EMOTE_GFX_COMPONENT_PATH)
set(DEFAULT_ASSETS_EXTRA_FILES "${EMOTE_GFX_COMPONENT_PATH}/emoji_normal")
endif()
elseif(CONFIG_BOARD_TYPE_ESP32S3_AUDIO_BOARD)
set(BOARD_TYPE "waveshare-s3-audio-board")
set(BUILTIN_TEXT_FONT font_puhui_basic_16_4)
@@ -406,11 +413,11 @@ elseif(CONFIG_BOARD_TYPE_GENJUTECH_S3_1_54TFT)
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
elseif(CONFIG_BOARD_TYPE_ESP32_CGC)
set(BOARD_TYPE "esp32-cgc")
set(BUILTIN_TEXT_FONT font_puhui_14_1)
set(BUILTIN_TEXT_FONT font_puhui_basic_14_1)
set(BUILTIN_ICON_FONT font_awesome_14_1)
elseif(CONFIG_BOARD_TYPE_ESP32_CGC_144)
set(BOARD_TYPE "esp32-cgc-144")
set(BUILTIN_TEXT_FONT font_puhui_14_1)
set(BUILTIN_TEXT_FONT font_puhui_basic_14_1)
set(BUILTIN_ICON_FONT font_awesome_14_1)
elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board)
set(BOARD_TYPE "esp-s3-lcd-ev-board")
@@ -499,12 +506,11 @@ if(CONFIG_USE_AUDIO_PROCESSOR)
else()
list(APPEND SOURCES "audio/processors/no_audio_processor.cc")
endif()
if(CONFIG_USE_AFE_WAKE_WORD)
if(CONFIG_IDF_TARGET_ESP32S3 OR CONFIG_IDF_TARGET_ESP32P4)
list(APPEND SOURCES "audio/wake_words/afe_wake_word.cc")
elseif(CONFIG_USE_ESP_WAKE_WORD)
list(APPEND SOURCES "audio/wake_words/esp_wake_word.cc")
elseif(CONFIG_USE_CUSTOM_WAKE_WORD)
list(APPEND SOURCES "audio/wake_words/custom_wake_word.cc")
else()
list(APPEND SOURCES "audio/wake_words/esp_wake_word.cc")
endif()
# Select language directory according to Kconfig
@@ -603,24 +609,16 @@ add_custom_target(lang_header ALL
)
# Find ESP-SR component dynamically
foreach(COMPONENT ${build_components})
if(COMPONENT MATCHES "espressif__esp-sr")
set(ESP_SR_COMPONENT ${COMPONENT})
idf_component_get_property(ESP_SR_COMPONENT_PATH ${ESP_SR_COMPONENT} COMPONENT_DIR)
set(ESP_SR_MODEL_PATH "${ESP_SR_COMPONENT_PATH}/model")
break()
endif()
endforeach()
find_component_by_pattern("espressif__esp-sr" ESP_SR_COMPONENT ESP_SR_COMPONENT_PATH)
if(ESP_SR_COMPONENT_PATH)
set(ESP_SR_MODEL_PATH "${ESP_SR_COMPONENT_PATH}/model")
endif()
# Find xiaozhi-fonts component dynamically
foreach(COMPONENT ${build_components})
if(COMPONENT MATCHES "xiaozhi-fonts")
set(XIAOZHI_FONTS_COMPONENT ${COMPONENT})
idf_component_get_property(XIAOZHI_FONTS_COMPONENT_PATH ${XIAOZHI_FONTS_COMPONENT} COMPONENT_DIR)
set(XIAOZHI_FONTS_PATH "${XIAOZHI_FONTS_COMPONENT_PATH}")
break()
endif()
endforeach()
find_component_by_pattern("xiaozhi-fonts" XIAOZHI_FONTS_COMPONENT XIAOZHI_FONTS_COMPONENT_PATH)
if(XIAOZHI_FONTS_COMPONENT_PATH)
set(XIAOZHI_FONTS_PATH "${XIAOZHI_FONTS_COMPONENT_PATH}")
endif()
if(CONFIG_BOARD_TYPE_ESP_HI)
set(URL "https://github.com/espressif2022/image_player/raw/main/test_apps/test_8bit")

View File

@@ -8,12 +8,11 @@
#include "processors/no_audio_processor.h"
#endif
#if CONFIG_USE_AFE_WAKE_WORD
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
#include "wake_words/afe_wake_word.h"
#elif CONFIG_USE_ESP_WAKE_WORD
#include "wake_words/esp_wake_word.h"
#elif CONFIG_USE_CUSTOM_WAKE_WORD
#include "wake_words/custom_wake_word.h"
#else
#include "wake_words/esp_wake_word.h"
#endif
#define TAG "AudioService"
@@ -50,16 +49,6 @@ void AudioService::Initialize(AudioCodec* codec) {
audio_processor_ = std::make_unique<NoAudioProcessor>();
#endif
#if CONFIG_USE_AFE_WAKE_WORD
wake_word_ = std::make_unique<AfeWakeWord>();
#elif CONFIG_USE_ESP_WAKE_WORD
wake_word_ = std::make_unique<EspWakeWord>();
#elif CONFIG_USE_CUSTOM_WAKE_WORD
wake_word_ = std::make_unique<CustomWakeWord>();
#else
wake_word_ = nullptr;
#endif
audio_processor_->OnOutput([this](std::vector<int16_t>&& data) {
PushTaskToEncodeQueue(kAudioTaskTypeEncodeToSendQueue, std::move(data));
});
@@ -71,14 +60,6 @@ void AudioService::Initialize(AudioCodec* codec) {
}
});
if (wake_word_) {
wake_word_->OnWakeWordDetected([this](const std::string& wake_word) {
if (callbacks_.on_wake_word_detected) {
callbacks_.on_wake_word_detected(wake_word);
}
});
}
esp_timer_create_args_t audio_power_timer_args = {
.callback = [](void* arg) {
AudioService* audio_service = (AudioService*)arg;
@@ -100,11 +81,11 @@ void AudioService::Start() {
#if CONFIG_USE_AUDIO_PROCESSOR
/* Start the audio input task */
xTaskCreate([](void* arg) {
xTaskCreatePinnedToCore([](void* arg) {
AudioService* audio_service = (AudioService*)arg;
audio_service->AudioInputTask();
vTaskDelete(NULL);
}, "audio_input", 2048 * 3, this, 8, &audio_input_task_handle_);
}, "audio_input", 2048 * 3, this, 8, &audio_input_task_handle_, 0);
/* Start the audio output task */
xTaskCreate([](void* arg) {
@@ -670,4 +651,36 @@ void AudioService::CheckAndUpdateAudioPowerState() {
void AudioService::SetModelsList(srmodel_list_t* models_list) {
models_list_ = models_list;
}
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
if (esp_srmodel_filter(models_list_, ESP_MN_PREFIX, NULL) != nullptr) {
wake_word_ = std::make_unique<CustomWakeWord>();
} else if (esp_srmodel_filter(models_list_, ESP_WN_PREFIX, NULL) != nullptr) {
wake_word_ = std::make_unique<AfeWakeWord>();
} else {
wake_word_ = nullptr;
}
#else
if (esp_srmodel_filter(models_list_, ESP_WN_PREFIX, NULL) != nullptr) {
wake_word_ = std::make_unique<EspWakeWord>();
} else {
wake_word_ = nullptr;
}
#endif
if (wake_word_) {
wake_word_->OnWakeWordDetected([this](const std::string& wake_word) {
if (callbacks_.on_wake_word_detected) {
callbacks_.on_wake_word_detected(wake_word);
}
});
}
}
bool AudioService::IsAfeWakeWord() {
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
return wake_word_ != nullptr && dynamic_cast<AfeWakeWord*>(wake_word_.get()) != nullptr;
#else
return false;
#endif
}

View File

@@ -94,6 +94,7 @@ public:
bool IsIdle();
bool IsWakeWordRunning() const { return xEventGroupGetBits(event_group_) & AS_EVENT_WAKE_WORD_RUNNING; }
bool IsAudioProcessorRunning() const { return xEventGroupGetBits(event_group_) & AS_EVENT_AUDIO_PROCESSOR_RUNNING; }
bool IsAfeWakeWord();
void EnableWakeWordDetection(bool enable);
void EnableVoiceProcessing(bool enable);

View File

@@ -91,8 +91,10 @@ bool CustomWakeWord::Initialize(AudioCodec* codec, srmodel_list_t* models_list)
if (models_list == nullptr) {
language_ = "cn";
models_ = esp_srmodel_init("model");
#if CONFIG_CUSTOM_WAKE_WORD
threshold_ = CONFIG_CUSTOM_WAKE_WORD_THRESHOLD / 100.0f;
commands_.push_back({CONFIG_CUSTOM_WAKE_WORD, CONFIG_CUSTOM_WAKE_WORD_DISPLAY, "wake"});
#endif
} else {
models_ = models_list;
ParseWakenetModelConfig();

View File

@@ -18,18 +18,6 @@ idf.py menuconfig
Xiaozhi Assistant -> Board Type -> AtomMatrix + Echo Base
```
**修改 flash 大小:**
```
Serial flasher config -> Flash size -> 4 MB
```
**修改分区表:**
```
Partition Table -> Custom partition CSV file -> partitions/v1/4m.csv
```
**编译:**
```bash

View File

@@ -4,8 +4,6 @@
{
"name": "atommatrix-echo-base",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\""
]
}
]

View File

@@ -5,7 +5,6 @@
"name": "atoms3-echo-base",
"sdkconfig_append": [
"CONFIG_SPIRAM=n",
"CONFIG_USE_AFE=n",
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\""
]

View File

@@ -4,8 +4,6 @@
{
"name": "bread-compact-esp32-lcd",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\"",
"LCD_ST7789_240X240_7PIN=y"
]
}

View File

@@ -18,18 +18,6 @@ idf.py menuconfig
Xiaozhi Assistant -> Board Type -> 面包板 ESP32 DevKit
```
**修改 flash 大小:**
```
Serial flasher config -> Flash size -> 4 MB
```
**修改分区表:**
```
Partition Table -> Custom partition CSV file -> partitions/v1/4m.csv
```
**编译:**
```bash

View File

@@ -4,16 +4,12 @@
{
"name": "bread-compact-esp32",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\"",
"CONFIG_OLED_SSD1306_128X64=y"
]
},
{
"name": "bread-compact-esp32-128x32",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\"",
"CONFIG_OLED_SSD1306_128X32=y"
]
}

View File

@@ -41,8 +41,8 @@ void WifiBoard::EnterWifiConfigMode() {
wifi_ap.SetSsidPrefix("Xiaozhi");
wifi_ap.Start();
// 等待 1 秒显示开发板信息
vTaskDelay(pdMS_TO_TICKS(1000));
// 等待 1.5 秒显示开发板信息
vTaskDelay(pdMS_TO_TICKS(1500));
// 显示 WiFi 配置 AP 的 SSID 和 Web 服务器 URL
std::string hint = Lang::Strings::CONNECT_TO_HOTSPOT;

View File

@@ -23,18 +23,6 @@ idf.py menuconfig
Xiaozhi Assistant -> Board Type -> ESP32 CGC 144
```
**修改 flash 大小:**
```
Serial flasher config -> Flash size -> 4 MB
```
**修改分区表:**
```
Partition Table -> Custom partition CSV file -> partitions/v1/4m.csv
```
**编译:**
```bash

View File

@@ -4,8 +4,6 @@
{
"name": "esp32-cgc-144",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\""
]
}
]

View File

@@ -29,18 +29,6 @@ Xiaozhi Assistant -> Board Type -> ESP32 CGC
Xiaozhi Assistant -> LCD Type -> "ST7735, 分辨率128*128"
```
**修改 flash 大小:**
```
Serial flasher config -> Flash size -> 4 MB
```
**修改分区表:**
```
Partition Table -> Custom partition CSV file -> partitions/v1/4m.csv
```
**编译:**
```bash

View File

@@ -4,8 +4,6 @@
{
"name": "esp32-cgc",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/4m.csv\"",
"CONFIG_LCD_ST7735_128X128=y"
]
}

View File

@@ -43,11 +43,8 @@ private:
}
void InitializePowerSaveTimer() {
#if CONFIG_USE_ESP_WAKE_WORD
sleep_timer_ = new SleepTimer(300);
#else
// Wake word detection will be disabled in light sleep mode
sleep_timer_ = new SleepTimer(30);
#endif
sleep_timer_->OnEnterLightSleepMode([this]() {
ESP_LOGI(TAG, "Enabling sleep mode");
// Show the standby screen

View File

@@ -43,11 +43,7 @@ private:
}
void InitializePowerSaveTimer() {
#if CONFIG_USE_ESP_WAKE_WORD
power_save_timer_ = new PowerSaveTimer(160, 300);
#else
power_save_timer_ = new PowerSaveTimer(160, 60);
#endif
power_save_timer_->OnEnterSleepMode([this]() {
GetDisplay()->SetPowerSaveMode(true);
});

View File

@@ -30,11 +30,7 @@ private:
PressToTalkMcpTool* press_to_talk_tool_ = nullptr;
void InitializePowerSaveTimer() {
#if CONFIG_USE_ESP_WAKE_WORD
power_save_timer_ = new PowerSaveTimer(160, 300);
#else
power_save_timer_ = new PowerSaveTimer(160, 60);
#endif
power_save_timer_->OnEnterSleepMode([this]() {
GetDisplay()->SetPowerSaveMode(true);
});

View File

@@ -1,7 +1,6 @@
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/v1/4m.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions/v1/4m.csv"
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/v2/4m.csv"
CONFIG_SR_WN_WN9_NIHAOXIAOZHI_TTS=y
CONFIG_ESP_TASK_WDT_TIMEOUT_S=20