wangzhibo
2026-09-11 659c470eba542383987aad227b7f918100f131fa
xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c
@@ -126,6 +126,45 @@
    ESP_LOGI(TAG, "offline command triggered: %s", OFFLINE_COMMAND_WORD);
}
bool Board_Is_Mode_Switch_Command(const char *command)
{
    return command &&
           (strcmp(command, OFFLINE_COMMAND_WORD) == 0 ||
            strcmp(command, OFFLINE_COMMAND_WORD_PINYIN) == 0 ||
            strcmp(command, OFFLINE_COMMAND_WORD_ALT) == 0 ||
            strcmp(command, OFFLINE_COMMAND_WORD_ALT_PINYIN) == 0);
}
bool Board_Is_Chat_Return_Command(const char *command)
{
    if (!command || command[0] == '\0') {
        return false;
    }
    return strcmp(command, OFFLINE_CHAT_WORD) == 0 ||
           strcmp(command, OFFLINE_CHAT_WORD_PINYIN) == 0 ||
           strcmp(command, OFFLINE_CHAT_WORD_FULL) == 0 ||
           strcmp(command, OFFLINE_CHAT_WORD_FULL_PINYIN) == 0 ||
           strcmp(command, OFFLINE_EXIT_REPEATER_WORD) == 0 ||
           strcmp(command, OFFLINE_EXIT_REPEATER_WORD_PINYIN) == 0 ||
           strcmp(command, OFFLINE_EXIT_SHADOWING_WORD) == 0 ||
           strcmp(command, OFFLINE_EXIT_SHADOWING_WORD_PINYIN) == 0 ||
           strstr(command, OFFLINE_CHAT_WORD_FULL) ||
           strstr(command, OFFLINE_CHAT_WORD) ||
           strstr(command, OFFLINE_EXIT_REPEATER_WORD) ||
           strstr(command, OFFLINE_EXIT_SHADOWING_WORD);
}
bool Board_Is_App_Launch_Command(const char *command)
{
    if (!command || command[0] == '\0') {
        return false;
    }
    return strcmp(command, OFFLINE_REPEATER_WORD) == 0 ||
           strcmp(command, OFFLINE_START_REPEATER_WORD) == 0 ||
           strstr(command, OFFLINE_REPEATER_WORD) ||
           strstr(command, OFFLINE_START_REPEATER_WORD);
}
bool Board_Handle_Offline_Command(const char *command)
{
    if (!command || Board_Is_Power_Off()) {
@@ -134,7 +173,7 @@
    if (Board_Handle_Voice_Command(command)) {
        return true;
    }
    if (strcmp(command, OFFLINE_COMMAND_WORD) != 0 && strcmp(command, OFFLINE_COMMAND_WORD_PINYIN) != 0) {
    if (!Board_Is_Mode_Switch_Command(command)) {
        return false;
    }
@@ -530,19 +569,23 @@
    return build_media_list_json(mp3_list_buffer, sizeof(mp3_list_buffer), mp3_name_has_extension);
}
static bool is_supported_mp3_speed(float speed)
float SDCard_Clamp_MP3_Speed(float speed)
{
    const float supported_speeds[] = {0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 2.0f};
    for (size_t i = 0; i < sizeof(supported_speeds) / sizeof(supported_speeds[0]); ++i) {
        float diff = speed - supported_speeds[i];
        if (diff < 0) {
            diff = -diff;
        }
        if (diff < 0.001f) {
            return true;
        }
    if (speed != speed) {
        return SDCARD_MP3_SPEED_DEFAULT;
    }
    return false;
    if (speed < SDCARD_MP3_SPEED_MIN) {
        return SDCARD_MP3_SPEED_MIN;
    }
    if (speed > SDCARD_MP3_SPEED_MAX) {
        return SDCARD_MP3_SPEED_MAX;
    }
    return speed;
}
bool SDCard_Resolve_MP3_Path(const char *mp3_name, char *path, size_t path_size)
{
    return resolve_mp3_path(mp3_name, path, path_size);
}
esp_err_t SDCard_Play_MP3(char *mp3_name)
@@ -557,11 +600,7 @@
esp_err_t SDCard_Play_MP3_With_Speed_Repeat(char *mp3_name, float speed, int repeat, bool power_off_after)
{
    if (!is_supported_mp3_speed(speed)) {
        ESP_LOGW(TAG, "invalid MP3 playback speed: %.2f", speed);
        SDCard_Resume_Play();
        return ESP_ERR_INVALID_ARG;
    }
    speed = SDCard_Clamp_MP3_Speed(speed);
    char path[SDCARD_PATH_MAX_LEN];
    if (!resolve_mp3_path(mp3_name, path, sizeof(path))) {
@@ -610,6 +649,22 @@
    return ESP_OK;
}
esp_err_t SDCard_Ensure_Business_Dir(const char *business_path)
{
    char sd_path[SDCARD_PATH_MAX_LEN];
    esp_err_t err = SDCard_Map_Business_Path(business_path, sd_path, sizeof(sd_path));
    if (err != ESP_OK) {
        return err;
    }
    err = mkdir_recursive(sd_path);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "ensure dir failed: %s", sd_path);
        return err;
    }
    ESP_LOGI(TAG, "ensure dir: %s", sd_path);
    return ESP_OK;
}
esp_err_t SDCard_Prepare_Business_File(const char *business_path,
                                       char *final_path,
                                       size_t final_path_size,