From 0fc9f551ec089cfaf63bf135c8097d0fc85652d8 Mon Sep 17 00:00:00 2001 From: Terrence Date: Tue, 10 Sep 2024 16:04:28 +0800 Subject: [PATCH] update version to 0.2.0 --- .gitignore | 3 +- CMakeLists.txt | 2 +- main/Application.cc | 9 +- main/Application.h | 3 +- main/CMakeLists.txt | 5 - main/FirmwareUpgrade.cc | 174 ----------------------------- main/FirmwareUpgrade.h | 24 ---- main/Kconfig.projbuild | 6 - main/OpusEncoder.cc | 72 ------------ main/OpusEncoder.h | 31 ------ main/SystemInfo.cc | 234 --------------------------------------- main/SystemInfo.h | 20 ---- main/WebSocketClient.cc | 132 ---------------------- main/WebSocketClient.h | 40 ------- main/idf_component.yml | 6 +- main/resampler_structs.h | 60 ---------- main/silk_resampler.h | 25 ----- publish.py | 51 +++++++++ 18 files changed, 63 insertions(+), 834 deletions(-) delete mode 100644 main/FirmwareUpgrade.cc delete mode 100644 main/FirmwareUpgrade.h delete mode 100644 main/OpusEncoder.cc delete mode 100644 main/OpusEncoder.h delete mode 100644 main/SystemInfo.cc delete mode 100644 main/SystemInfo.h delete mode 100644 main/WebSocketClient.cc delete mode 100644 main/WebSocketClient.h delete mode 100644 main/resampler_structs.h delete mode 100644 main/silk_resampler.h create mode 100644 publish.py diff --git a/.gitignore b/.gitignore index 22f77cea..e6c7479e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ build/ .devcontainer/ sdkconfig.old sdkconfig -dependencies.lock \ No newline at end of file +dependencies.lock +.env diff --git a/CMakeLists.txt b/CMakeLists.txt index 42eb139b..a27c2313 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -set(PROJECT_VER "0.1.1") +set(PROJECT_VER "0.2.0") include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(xiaozhi) diff --git a/main/Application.cc b/main/Application.cc index 91e1d629..70cf9667 100644 --- a/main/Application.cc +++ b/main/Application.cc @@ -6,9 +6,8 @@ #include "model_path.h" #include "SystemInfo.h" #include "cJSON.h" -#include "silk_resampler.h" -#define TAG "application" +#define TAG "Application" Application::Application() { @@ -29,7 +28,7 @@ Application::Application() { opus_encoder_.Configure(CONFIG_AUDIO_INPUT_SAMPLE_RATE, 1); opus_decoder_ = opus_decoder_create(opus_decode_sample_rate_, 1, NULL); if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) { - assert(0 == silk_resampler_init(&resampler_state_, opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE, 1)); + opus_resampler_.Configure(opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE); } } @@ -461,7 +460,7 @@ void Application::AudioDecodeTask() { if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) { int target_size = frame_size * CONFIG_AUDIO_OUTPUT_SAMPLE_RATE / opus_decode_sample_rate_; std::vector resampled(target_size); - assert(0 == silk_resampler(&resampler_state_, resampled.data(), packet->pcm.data(), frame_size)); + opus_resampler_.Process(packet->pcm.data(), frame_size, resampled.data(), target_size); packet->pcm = std::move(resampled); } } @@ -479,7 +478,7 @@ void Application::SetDecodeSampleRate(int sample_rate) { opus_decode_sample_rate_ = sample_rate; opus_decoder_ = opus_decoder_create(opus_decode_sample_rate_, 1, NULL); if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) { - assert(0 == silk_resampler_init(&resampler_state_, opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE, 1)); + opus_resampler_.Configure(opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE); } } diff --git a/main/Application.h b/main/Application.h index 6693bf5f..5107abdd 100644 --- a/main/Application.h +++ b/main/Application.h @@ -3,6 +3,7 @@ #include "AudioDevice.h" #include "OpusEncoder.h" +#include "OpusResampler.h" #include "WebSocketClient.h" #include "FirmwareUpgrade.h" @@ -74,7 +75,7 @@ private: int opus_duration_ms_ = 60; int opus_decode_sample_rate_ = CONFIG_AUDIO_OUTPUT_SAMPLE_RATE; - silk_resampler_state_struct resampler_state_; + OpusResampler opus_resampler_; TaskHandle_t wake_word_encode_task_ = nullptr; StaticTask_t wake_word_encode_task_buffer_; diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index bcf63ef2..fbc6795f 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,12 +1,7 @@ set(SOURCES "AudioDevice.cc" - "SystemInfo.cc" "SystemReset.cc" - "WebSocketClient.cc" - "OpusEncoder.cc" - "Application.cc" "main.cc" - "FirmwareUpgrade.cc" ) idf_component_register(SRCS ${SOURCES} diff --git a/main/FirmwareUpgrade.cc b/main/FirmwareUpgrade.cc deleted file mode 100644 index bb6b6651..00000000 --- a/main/FirmwareUpgrade.cc +++ /dev/null @@ -1,174 +0,0 @@ -#include "FirmwareUpgrade.h" -#include "SystemInfo.h" -#include "esp_log.h" -#include "esp_ota_ops.h" -#include "esp_https_ota.h" -#include "esp_partition.h" -#include "esp_http_client.h" -#include "esp_crt_bundle.h" -#include "cJSON.h" - - -#define TAG "FirmwareUpgrade" - - -FirmwareUpgrade::FirmwareUpgrade() { -} - -FirmwareUpgrade::~FirmwareUpgrade() { -} - -void FirmwareUpgrade::CheckVersion() { - std::string current_version = esp_app_get_description()->version; - ESP_LOGI(TAG, "Current version: %s", current_version.c_str()); - - // Get device info and request the latest firmware from the server - std::string device_info = SystemInfo::GetJsonString(); - - esp_http_client_config_t config = {}; - config.url = CONFIG_OTA_UPGRADE_URL; - config.crt_bundle_attach = esp_crt_bundle_attach; - esp_http_client_handle_t client = esp_http_client_init(&config); - esp_http_client_set_method(client, HTTP_METHOD_POST); - esp_http_client_set_header(client, "Content-Type", "application/json"); - esp_http_client_set_header(client, "Device-Id", SystemInfo::GetMacAddress().c_str()); - esp_err_t err = esp_http_client_open(client, device_info.length()); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to perform HTTP request: %s", esp_err_to_name(err)); - esp_http_client_cleanup(client); - return; - } - auto written = esp_http_client_write(client, device_info.data(), device_info.length()); - if (written < 0) { - ESP_LOGE(TAG, "Failed to write request body: %s", esp_err_to_name(err)); - esp_http_client_cleanup(client); - return; - } - int content_length = esp_http_client_fetch_headers(client); - if (content_length <= 0) { - ESP_LOGE(TAG, "Failed to fetch headers"); - esp_http_client_cleanup(client); - return; - } - - std::string response; - response.resize(content_length); - int ret = esp_http_client_read_response(client, (char*)response.data(), content_length); - if (ret <= 0) { - ESP_LOGE(TAG, "Failed to read response content_length=%d", content_length); - esp_http_client_cleanup(client); - return; - } - esp_http_client_close(client); - esp_http_client_cleanup(client); - - // Response: { "firmware": { "version": "1.0.0", "url": "http://" } } - // Parse the JSON response and check if the version is newer - // If it is, set has_new_version_ to true and store the new version and URL - - cJSON *root = cJSON_Parse(response.c_str()); - if (root == NULL) { - ESP_LOGE(TAG, "Failed to parse JSON response"); - return; - } - cJSON *firmware = cJSON_GetObjectItem(root, "firmware"); - if (firmware == NULL) { - ESP_LOGE(TAG, "Failed to get firmware object"); - cJSON_Delete(root); - return; - } - cJSON *version = cJSON_GetObjectItem(firmware, "version"); - if (version == NULL) { - ESP_LOGE(TAG, "Failed to get version object"); - cJSON_Delete(root); - return; - } - cJSON *url = cJSON_GetObjectItem(firmware, "url"); - if (url == NULL) { - ESP_LOGE(TAG, "Failed to get url object"); - cJSON_Delete(root); - return; - } - - new_version_ = version->valuestring; - new_version_url_ = url->valuestring; - cJSON_Delete(root); - - has_new_version_ = new_version_ != current_version; - if (has_new_version_) { - ESP_LOGI(TAG, "New version available: %s", new_version_.c_str()); - } else { - ESP_LOGI(TAG, "No new version available"); - } - return; -} - -void FirmwareUpgrade::MarkValid() { - auto partition = esp_ota_get_running_partition(); - if (strcmp(partition->label, "factory") == 0) { - ESP_LOGI(TAG, "Running from factory partition, skipping"); - return; - } - - ESP_LOGI(TAG, "Running partition: %s", partition->label); - esp_ota_img_states_t state; - if (esp_ota_get_state_partition(partition, &state) != ESP_OK) { - ESP_LOGE(TAG, "Failed to get state of partition"); - return; - } - - if (state == ESP_OTA_IMG_PENDING_VERIFY) { - ESP_LOGI(TAG, "Marking firmware as valid"); - esp_ota_mark_app_valid_cancel_rollback(); - } -} - -void FirmwareUpgrade::Upgrade(std::string firmware_url) { - ESP_LOGI(TAG, "Upgrading firmware from %s", firmware_url.c_str()); - - esp_http_client_config_t config = {}; - config.url = firmware_url.c_str(); - config.crt_bundle_attach = esp_crt_bundle_attach; - config.event_handler = [](esp_http_client_event_t *evt) { - switch (evt->event_id) { - case HTTP_EVENT_ERROR: - ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); - break; - case HTTP_EVENT_ON_CONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); - break; - case HTTP_EVENT_HEADER_SENT: - ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); - break; - case HTTP_EVENT_ON_HEADER: - ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); - break; - case HTTP_EVENT_ON_DATA: - ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); - break; - case HTTP_EVENT_ON_FINISH: - ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); - break; - case HTTP_EVENT_DISCONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); - break; - case HTTP_EVENT_REDIRECT: - ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT"); - break; - } - return ESP_OK; - }; - config.keep_alive_enable = true; - - esp_https_ota_config_t ota_config = {}; - ota_config.http_config = &config; - esp_err_t err = esp_https_ota(&ota_config); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to upgrade firmware: %s", esp_err_to_name(err)); - return; - } - - ESP_LOGI(TAG, "Firmware upgrade successful, rebooting in 3 seconds..."); - vTaskDelay(pdMS_TO_TICKS(3000)); - esp_restart(); -} diff --git a/main/FirmwareUpgrade.h b/main/FirmwareUpgrade.h deleted file mode 100644 index 8fac7a42..00000000 --- a/main/FirmwareUpgrade.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _FIRMWARE_UPGRADE_H -#define _FIRMWARE_UPGRADE_H - -#include - -class FirmwareUpgrade { -public: - FirmwareUpgrade(); - ~FirmwareUpgrade(); - - void CheckVersion(); - bool HasNewVersion() { return has_new_version_; } - void StartUpgrade() { Upgrade(new_version_url_); } - void MarkValid(); - -private: - bool has_new_version_ = false; - std::string new_version_; - std::string new_version_url_; - - void Upgrade(std::string firmware_url); -}; - -#endif // _FIRMWARE_UPGRADE_H diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index e945f6a7..59fadb88 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -1,11 +1,5 @@ menu "Xiaozhi Assistant" -config OTA_UPGRADE_URL - string "OTA Upgrade URL" - default "https://" - help - The application will access this URL to check for updates when it starts and every 24 hours. - config WEBSOCKET_URL string "Websocket URL" default "wss://" diff --git a/main/OpusEncoder.cc b/main/OpusEncoder.cc deleted file mode 100644 index 6970c38d..00000000 --- a/main/OpusEncoder.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "OpusEncoder.h" -#include "esp_err.h" -#include "esp_log.h" - -#define TAG "OpusEncoder" - -OpusEncoder::OpusEncoder() { -} - -OpusEncoder::~OpusEncoder() { - if (audio_enc_ != nullptr) { - opus_encoder_destroy(audio_enc_); - } -} - -void OpusEncoder::Configure(int sample_rate, int channels, int duration_ms) { - if (audio_enc_ != nullptr) { - opus_encoder_destroy(audio_enc_); - audio_enc_ = nullptr; - } - - int error; - audio_enc_ = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_VOIP, &error); - if (audio_enc_ == nullptr) { - ESP_LOGE(TAG, "Failed to create audio encoder, error code: %d", error); - return; - } - - // Set DTX - opus_encoder_ctl(audio_enc_, OPUS_SET_DTX(1)); - SetComplexity(5); - - frame_size_ = sample_rate / 1000 * duration_ms; - out_buffer_.resize(sample_rate * channels * sizeof(int16_t)); -} - -void OpusEncoder::SetComplexity(int complexity) { - if (audio_enc_ != nullptr) { - opus_encoder_ctl(audio_enc_, OPUS_SET_COMPLEXITY(complexity)); - } -} - -void OpusEncoder::Encode(const iovec pcm, std::function handler) { - if (audio_enc_ == nullptr) { - ESP_LOGE(TAG, "Audio encoder is not configured"); - return; - } - - auto pcm_data = (int16_t*)pcm.iov_base; - in_buffer_.insert(in_buffer_.end(), pcm_data, pcm_data + pcm.iov_len / sizeof(int16_t)); - - while (in_buffer_.size() >= frame_size_) { - auto ret = opus_encode(audio_enc_, in_buffer_.data(), frame_size_, out_buffer_.data(), out_buffer_.size()); - if (ret < 0) { - ESP_LOGE(TAG, "Failed to encode audio, error code: %ld", ret); - return; - } - - if (handler != nullptr) { - handler(iovec { out_buffer_.data(), (size_t)ret }); - } - - in_buffer_.erase(in_buffer_.begin(), in_buffer_.begin() + frame_size_); - } -} - -void OpusEncoder::ResetState() { - if (audio_enc_ != nullptr) { - opus_encoder_ctl(audio_enc_, OPUS_RESET_STATE); - } - in_buffer_.clear(); -} diff --git a/main/OpusEncoder.h b/main/OpusEncoder.h deleted file mode 100644 index ae8e1998..00000000 --- a/main/OpusEncoder.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _OPUS_ENCODER_H_ -#define _OPUS_ENCODER_H_ - -#include -#include -#include -#include - -#include "lwip/sockets.h" -#include "opus.h" - - -class OpusEncoder { -public: - OpusEncoder(); - ~OpusEncoder(); - - void Configure(int sample_rate, int channels, int duration_ms = 60); - void SetComplexity(int complexity); - void Encode(const iovec pcm, std::function handler); - bool IsBufferEmpty() const { return in_buffer_.empty(); } - void ResetState(); - -private: - struct OpusEncoder* audio_enc_ = nullptr; - int frame_size_; - std::vector out_buffer_; - std::vector in_buffer_; -}; - -#endif // _OPUS_ENCODER_H_ diff --git a/main/SystemInfo.cc b/main/SystemInfo.cc deleted file mode 100644 index efcbf25e..00000000 --- a/main/SystemInfo.cc +++ /dev/null @@ -1,234 +0,0 @@ -#include "SystemInfo.h" -#include "freertos/task.h" -#include "esp_log.h" -#include "esp_flash.h" -#include "esp_mac.h" -#include "esp_chip_info.h" -#include "esp_system.h" -#include "esp_partition.h" -#include "esp_app_desc.h" -#include "esp_psram.h" -#include "esp_wifi.h" -#include "esp_ota_ops.h" - - -#define TAG "SystemInfo" - -size_t SystemInfo::GetFlashSize() { - uint32_t flash_size; - if (esp_flash_get_size(NULL, &flash_size) != ESP_OK) { - ESP_LOGE(TAG, "Failed to get flash size"); - return 0; - } - return (size_t)flash_size; -} - -size_t SystemInfo::GetMinimumFreeHeapSize() { - return esp_get_minimum_free_heap_size(); -} - -size_t SystemInfo::GetFreeHeapSize() { - return esp_get_free_heap_size(); -} - -std::string SystemInfo::GetMacAddress() { - uint8_t mac[6]; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - char mac_str[18]; - snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return std::string(mac_str); -} - -std::string SystemInfo::GetChipModelName() { - return std::string(CONFIG_IDF_TARGET); -} - -std::string SystemInfo::GetJsonString() { - /* - { - "flash_size": 4194304, - "psram_size": 0, - "minimum_free_heap_size": 123456, - "mac_address": "00:00:00:00:00:00", - "chip_model_name": "esp32s3", - "chip_info": { - "model": 1, - "cores": 2, - "revision": 0, - "features": 0 - }, - "application": { - "name": "my-app", - "version": "1.0.0", - "compile_time": "2021-01-01T00:00:00Z" - "idf_version": "4.2-dev" - "elf_sha256": "" - }, - "partition_table": [ - "app": { - "label": "app", - "type": 1, - "subtype": 2, - "address": 0x10000, - "size": 0x100000 - } - ], - "ota": { - "label": "ota_0" - }, - "wifi": { - "ssid": "my-wifi", - "rss": -50, - "channel": 6 - } - } - */ - std::string json = "{"; - json += "\"flash_size\":" + std::to_string(GetFlashSize()) + ","; - json += "\"psram_size\":" + std::to_string(esp_psram_get_size()) + ","; - json += "\"minimum_free_heap_size\":" + std::to_string(GetMinimumFreeHeapSize()) + ","; - json += "\"mac_address\":\"" + GetMacAddress() + "\","; - json += "\"chip_model_name\":\"" + GetChipModelName() + "\","; - json += "\"chip_info\":{"; - - esp_chip_info_t chip_info; - esp_chip_info(&chip_info); - json += "\"model\":" + std::to_string(chip_info.model) + ","; - json += "\"cores\":" + std::to_string(chip_info.cores) + ","; - json += "\"revision\":" + std::to_string(chip_info.revision) + ","; - json += "\"features\":" + std::to_string(chip_info.features); - json += "},"; - - json += "\"application\":{"; - auto app_desc = esp_app_get_description(); - json += "\"name\":\"" + std::string(app_desc->project_name) + "\","; - json += "\"version\":\"" + std::string(app_desc->version) + "\","; - json += "\"compile_time\":\"" + std::string(app_desc->date) + "T" + std::string(app_desc->time) + "Z\","; - json += "\"idf_version\":\"" + std::string(app_desc->idf_ver) + "\","; - - char sha256_str[65]; - for (int i = 0; i < 32; i++) { - snprintf(sha256_str + i * 2, sizeof(sha256_str) - i * 2, "%02x", app_desc->app_elf_sha256[i]); - } - json += "\"elf_sha256\":\"" + std::string(sha256_str) + "\""; - json += "},"; - - json += "\"partition_table\": ["; - esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL); - while (it) { - const esp_partition_t *partition = esp_partition_get(it); - json += "{"; - json += "\"label\":\"" + std::string(partition->label) + "\","; - json += "\"type\":" + std::to_string(partition->type) + ","; - json += "\"subtype\":" + std::to_string(partition->subtype) + ","; - json += "\"address\":" + std::to_string(partition->address) + ","; - json += "\"size\":" + std::to_string(partition->size); - json += "},"; - it = esp_partition_next(it); - } - json.pop_back(); // Remove the last comma - json += "],"; - - json += "\"ota\":{"; - auto ota_partition = esp_ota_get_running_partition(); - json += "\"label\":\"" + std::string(ota_partition->label) + "\""; - json += "},"; - - wifi_ap_record_t ap_info; - esp_wifi_sta_get_ap_info(&ap_info); - json += "\"wifi\":{"; - json += "\"ssid\":\"" + std::string(reinterpret_cast(ap_info.ssid)) + "\","; - json += "\"rssi\":" + std::to_string(ap_info.rssi) + ","; - json += "\"channel\":" + std::to_string(ap_info.primary); - json += "}"; - - // Close the JSON object - json += "}"; - return json; -} - -esp_err_t SystemInfo::PrintRealTimeStats(TickType_t xTicksToWait) { - #define ARRAY_SIZE_OFFSET 5 - TaskStatus_t *start_array = NULL, *end_array = NULL; - UBaseType_t start_array_size, end_array_size; - configRUN_TIME_COUNTER_TYPE start_run_time, end_run_time; - esp_err_t ret; - uint32_t total_elapsed_time; - - //Allocate array to store current task states - start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; - start_array = (TaskStatus_t*)malloc(sizeof(TaskStatus_t) * start_array_size); - if (start_array == NULL) { - ret = ESP_ERR_NO_MEM; - goto exit; - } - //Get current task states - start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time); - if (start_array_size == 0) { - ret = ESP_ERR_INVALID_SIZE; - goto exit; - } - - vTaskDelay(xTicksToWait); - - //Allocate array to store tasks states post delay - end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; - end_array = (TaskStatus_t*)malloc(sizeof(TaskStatus_t) * end_array_size); - if (end_array == NULL) { - ret = ESP_ERR_NO_MEM; - goto exit; - } - //Get post delay task states - end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time); - if (end_array_size == 0) { - ret = ESP_ERR_INVALID_SIZE; - goto exit; - } - - //Calculate total_elapsed_time in units of run time stats clock period. - total_elapsed_time = (end_run_time - start_run_time); - if (total_elapsed_time == 0) { - ret = ESP_ERR_INVALID_STATE; - goto exit; - } - - printf("| Task | Run Time | Percentage\n"); - //Match each task in start_array to those in the end_array - for (int i = 0; i < start_array_size; i++) { - int k = -1; - for (int j = 0; j < end_array_size; j++) { - if (start_array[i].xHandle == end_array[j].xHandle) { - k = j; - //Mark that task have been matched by overwriting their handles - start_array[i].xHandle = NULL; - end_array[j].xHandle = NULL; - break; - } - } - //Check if matching task found - if (k >= 0) { - uint32_t task_elapsed_time = end_array[k].ulRunTimeCounter - start_array[i].ulRunTimeCounter; - uint32_t percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * CONFIG_FREERTOS_NUMBER_OF_CORES); - printf("| %-16s | %8lu | %4lu%%\n", start_array[i].pcTaskName, task_elapsed_time, percentage_time); - } - } - - //Print unmatched tasks - for (int i = 0; i < start_array_size; i++) { - if (start_array[i].xHandle != NULL) { - printf("| %s | Deleted\n", start_array[i].pcTaskName); - } - } - for (int i = 0; i < end_array_size; i++) { - if (end_array[i].xHandle != NULL) { - printf("| %s | Created\n", end_array[i].pcTaskName); - } - } - ret = ESP_OK; - -exit: //Common return path - free(start_array); - free(end_array); - return ret; -} - diff --git a/main/SystemInfo.h b/main/SystemInfo.h deleted file mode 100644 index b0744d2b..00000000 --- a/main/SystemInfo.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _SYSTEM_INFO_H_ -#define _SYSTEM_INFO_H_ - -#include - -#include "esp_err.h" -#include "freertos/FreeRTOS.h" - -class SystemInfo { -public: - static size_t GetFlashSize(); - static size_t GetMinimumFreeHeapSize(); - static size_t GetFreeHeapSize(); - static std::string GetMacAddress(); - static std::string GetChipModelName(); - static std::string GetJsonString(); - static esp_err_t PrintRealTimeStats(TickType_t xTicksToWait); -}; - -#endif // _SYSTEM_INFO_H_ diff --git a/main/WebSocketClient.cc b/main/WebSocketClient.cc deleted file mode 100644 index b553f272..00000000 --- a/main/WebSocketClient.cc +++ /dev/null @@ -1,132 +0,0 @@ -#include "WebSocketClient.h" -#include -#include "freertos/task.h" -#include "esp_log.h" -#include "esp_crt_bundle.h" - - -#define TAG "WebSocket" -#define TIMEOUT_TICKS pdMS_TO_TICKS(3000) - -WebSocketClient::WebSocketClient(bool auto_reconnect) { - event_group_ = xEventGroupCreate(); - - esp_websocket_client_config_t config = {}; - config.task_prio = 1; - config.disable_auto_reconnect = !auto_reconnect; - config.crt_bundle_attach = esp_crt_bundle_attach; - client_ = esp_websocket_client_init(&config); - assert(client_ != NULL); - - esp_websocket_register_events(client_, WEBSOCKET_EVENT_ANY, [](void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - WebSocketClient* ws = (WebSocketClient*)arg; - esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data; - switch (event_id) - { - case WEBSOCKET_EVENT_BEFORE_CONNECT: - break; - case WEBSOCKET_EVENT_CONNECTED: - if (ws->on_connected_) { - ws->on_connected_(); - } - xEventGroupSetBits(ws->event_group_, WEBSOCKET_CONNECTED_BIT); - break; - case WEBSOCKET_EVENT_DISCONNECTED: - xEventGroupSetBits(ws->event_group_, WEBSOCKET_DISCONNECTED_BIT); - break; - case WEBSOCKET_EVENT_DATA: - if (data->data_len != data->payload_len) { - ESP_LOGE(TAG, "Payload segmentating is not supported, data_len: %d, payload_len: %d", data->data_len, data->payload_len); - break; - } - if (data->op_code == 8) { // Websocket close - ESP_LOGI(TAG, "Websocket closed"); - if (ws->on_closed_) { - ws->on_closed_(); - } - } else if (data->op_code == 9) { - // Websocket ping - } else if (data->op_code == 10) { - // Websocket pong - } else if (data->op_code == 1) { - // Websocket text - if (ws->on_data_) { - ws->on_data_(data->data_ptr, data->data_len, false); - } - } else if (data->op_code == 2) { - // Websocket binary - if (ws->on_data_) { - ws->on_data_(data->data_ptr, data->data_len, true); - } - } else { - ESP_LOGI(TAG, "Unknown opcode: %d", data->op_code); - } - break; - case WEBSOCKET_EVENT_ERROR: - if (ws->on_error_) { - ws->on_error_(data->error_handle.error_type); - } - xEventGroupSetBits(ws->event_group_, WEBSOCKET_ERROR_BIT); - break; - case WEBSOCKET_EVENT_CLOSED: - break; - default: - ESP_LOGI(TAG, "Event %ld", event_id); - } - }, this); -} - -WebSocketClient::~WebSocketClient() { - esp_websocket_client_close(client_, TIMEOUT_TICKS); - ESP_LOGI(TAG, "Destroying websocket client"); - esp_websocket_client_destroy(client_); -} - -void WebSocketClient::SetHeader(const char* key, const char* value) { - esp_websocket_client_append_header(client_, key, value); -} - -bool WebSocketClient::Connect(const char* uri) { - esp_websocket_client_set_uri(client_, uri); - esp_websocket_client_start(client_); - - // Wait for the connection to be established or an error - EventBits_t bits = xEventGroupWaitBits(event_group_, WEBSOCKET_CONNECTED_BIT | WEBSOCKET_ERROR_BIT, pdFALSE, pdFALSE, TIMEOUT_TICKS); - return bits & WEBSOCKET_CONNECTED_BIT; -} - -void WebSocketClient::Send(const void* data, size_t len, bool binary) { - if (binary) { - esp_websocket_client_send_bin(client_, (const char*)data, len, portMAX_DELAY); - } else { - esp_websocket_client_send_text(client_, (const char*)data, len, portMAX_DELAY); - } -} - -void WebSocketClient::Send(const std::string& data) { - Send(data.c_str(), data.size(), false); -} - -void WebSocketClient::OnClosed(std::function callback) { - on_closed_ = callback; -} - -void WebSocketClient::OnData(std::function callback) { - on_data_ = callback; -} - -void WebSocketClient::OnError(std::function callback) { - on_error_ = callback; -} - -void WebSocketClient::OnConnected(std::function callback) { - on_connected_ = callback; -} - -void WebSocketClient::OnDisconnected(std::function callback) { - on_disconnected_ = callback; -} - -bool WebSocketClient::IsConnected() const { - return esp_websocket_client_is_connected(client_); -} diff --git a/main/WebSocketClient.h b/main/WebSocketClient.h deleted file mode 100644 index 71372119..00000000 --- a/main/WebSocketClient.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _WEBSOCKET_CLIENT_H_ -#define _WEBSOCKET_CLIENT_H_ - -#include -#include -#include "esp_websocket_client.h" -#include "freertos/event_groups.h" - -#define WEBSOCKET_CONNECTED_BIT BIT0 -#define WEBSOCKET_DISCONNECTED_BIT BIT1 -#define WEBSOCKET_ERROR_BIT BIT2 - -class WebSocketClient { -public: - WebSocketClient(bool auto_reconnect = false); - ~WebSocketClient(); - - void SetHeader(const char* key, const char* value); - bool IsConnected() const; - bool Connect(const char* uri); - void Send(const std::string& data); - void Send(const void* data, size_t len, bool binary = false); - - void OnConnected(std::function callback); - void OnDisconnected(std::function callback); - void OnData(std::function callback); - void OnError(std::function callback); - void OnClosed(std::function callback); - -private: - esp_websocket_client_handle_t client_ = NULL; - EventGroupHandle_t event_group_; - std::function on_data_; - std::function on_error_; - std::function on_closed_; - std::function on_connected_; - std::function on_disconnected_; -}; - -#endif // _WEBSOCKET_CLIENT_H_ diff --git a/main/idf_component.yml b/main/idf_component.yml index d2487beb..f0f1952d 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,10 +1,10 @@ ## IDF Component Manager Manifest File dependencies: - 78/esp-opus: "^1.0.2" 78/esp-builtin-led: "^1.0.0" 78/esp-wifi-connect: "^1.0.0" - espressif/esp_websocket_client: "^1.2.3" - espressif/led_strip: "*" + 78/esp-ota: "^1.0.0" + 78/esp-websocket: "^1.0.0" + 78/esp-opus-encoder: "^1.0.0" espressif/esp-sr: "^1.9.0" ## Required IDF version idf: diff --git a/main/resampler_structs.h b/main/resampler_structs.h deleted file mode 100644 index 9e9457d1..00000000 --- a/main/resampler_structs.h +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_RESAMPLER_STRUCTS_H -#define SILK_RESAMPLER_STRUCTS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define SILK_RESAMPLER_MAX_FIR_ORDER 36 -#define SILK_RESAMPLER_MAX_IIR_ORDER 6 - -typedef struct _silk_resampler_state_struct{ - opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ - union{ - opus_int32 i32[ SILK_RESAMPLER_MAX_FIR_ORDER ]; - opus_int16 i16[ SILK_RESAMPLER_MAX_FIR_ORDER ]; - } sFIR; - opus_int16 delayBuf[ 48 ]; - opus_int resampler_function; - opus_int batchSize; - opus_int32 invRatio_Q16; - opus_int FIR_Order; - opus_int FIR_Fracs; - opus_int Fs_in_kHz; - opus_int Fs_out_kHz; - opus_int inputDelay; - const opus_int16 *Coefs; -} silk_resampler_state_struct; - -#ifdef __cplusplus -} -#endif -#endif /* SILK_RESAMPLER_STRUCTS_H */ - diff --git a/main/silk_resampler.h b/main/silk_resampler.h deleted file mode 100644 index 1f4518d1..00000000 --- a/main/silk_resampler.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _SILK_RESAMPLER_H_ -#define _SILK_RESAMPLER_H_ - - -/*! - * Initialize/reset the resampler state for a given pair of input/output sampling rates -*/ -extern "C" opus_int silk_resampler_init( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ - opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ - opus_int forEnc /* I If 1: encoder; if 0: decoder */ -); - -/*! - * Resampler: convert from one sampling rate to another - */ -extern "C" opus_int silk_resampler( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -); - -#endif // _SILK_RESAMPLER_H_ diff --git a/publish.py b/publish.py new file mode 100644 index 00000000..cc7c6445 --- /dev/null +++ b/publish.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python3 +from dotenv import load_dotenv +load_dotenv() + +import os +import oss2 +import json + +def get_version(): + with open('CMakeLists.txt', 'r') as f: + for line in f: + if line.startswith('set(PROJECT_VER'): + return line.split('"')[1] + return '0.0.0' + +def upload_bin_to_oss(bin_path, oss_key): + auth = oss2.Auth(os.environ['OSS_ACCESS_KEY_ID'], os.environ['OSS_ACCESS_KEY_SECRET']) + bucket = oss2.Bucket(auth, os.environ['OSS_ENDPOINT'], os.environ['OSS_BUCKET_NAME']) + bucket.put_object(oss_key, open(bin_path, 'rb')) + + +if __name__ == '__main__': + # 获取版本号 + version = get_version() + print(f'version: {version}') + + # 上传 bin 文件到 OSS + upload_bin_to_oss('build/xiaozhi.bin', f'firmwares/xiaozhi-{version}.bin') + + # File URL + file_url = os.path.join(os.environ['OSS_BUCKET_URL'], f'firmwares/xiaozhi-{version}.bin') + print(f'Uploaded bin to OSS: {file_url}') + + firmware_json = { + "version": version, + "url": file_url + } + with open(f"build/firmware.json", "w") as f: + json.dump(firmware_json, f, indent=4) + + # copy firmware.json to server + firmware_config_path = os.environ['FIRMWARE_CONFIG_PATH'] + ret = os.system(f'scp build/firmware.json {firmware_config_path}') + if ret != 0: + print(f'Failed to copy firmware.json to server') + exit(1) + print(f'Copied firmware.json to server: {firmware_config_path}') + + + +