| | |
| | | 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()) { |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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) |
| | |
| | | |
| | | 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))) { |
| | |
| | | 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, |