forked from xiaozhi/xiaozhi-esp32
fixbug: internal memory not enough
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
# CMakeLists in this exact order for cmake to work correctly
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(PROJECT_VER "0.7.1")
|
set(PROJECT_VER "0.7.2")
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(xiaozhi)
|
project(xiaozhi)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ void Application::Start() {
|
|||||||
auto codec = board.GetAudioCodec();
|
auto codec = board.GetAudioCodec();
|
||||||
opus_decode_sample_rate_ = codec->output_sample_rate();
|
opus_decode_sample_rate_ = codec->output_sample_rate();
|
||||||
opus_decoder_ = opus_decoder_create(opus_decode_sample_rate_, 1, NULL);
|
opus_decoder_ = opus_decoder_create(opus_decode_sample_rate_, 1, NULL);
|
||||||
opus_encoder_.Configure(codec->input_sample_rate(), 1);
|
opus_encoder_.Configure(16000, 1);
|
||||||
if (codec->input_sample_rate() != 16000) {
|
if (codec->input_sample_rate() != 16000) {
|
||||||
input_resampler_.Configure(codec->input_sample_rate(), 16000);
|
input_resampler_.Configure(codec->input_sample_rate(), 16000);
|
||||||
reference_resampler_.Configure(codec->input_sample_rate(), 16000);
|
reference_resampler_.Configure(codec->input_sample_rate(), 16000);
|
||||||
@@ -236,6 +236,17 @@ void Application::Start() {
|
|||||||
}, "check_new_version", 4096 * 2, this, 1, NULL);
|
}, "check_new_version", 4096 * 2, this, 1, NULL);
|
||||||
|
|
||||||
#ifdef CONFIG_USE_AFE_SR
|
#ifdef CONFIG_USE_AFE_SR
|
||||||
|
audio_processor_.Initialize(codec->input_channels(), codec->input_reference());
|
||||||
|
audio_processor_.OnOutput([this](std::vector<int16_t>&& data) {
|
||||||
|
Schedule([this, data = std::move(data)]() {
|
||||||
|
if (chat_state_ == kChatStateListening) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
audio_encode_queue_.emplace_back(std::move(data));
|
||||||
|
cv_.notify_all();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
wake_word_detect_.Initialize(codec->input_channels(), codec->input_reference());
|
wake_word_detect_.Initialize(codec->input_channels(), codec->input_reference());
|
||||||
wake_word_detect_.OnVadStateChange([this](bool speaking) {
|
wake_word_detect_.OnVadStateChange([this](bool speaking) {
|
||||||
Schedule([this, speaking]() {
|
Schedule([this, speaking]() {
|
||||||
@@ -284,17 +295,6 @@ void Application::Start() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
wake_word_detect_.StartDetection();
|
wake_word_detect_.StartDetection();
|
||||||
|
|
||||||
audio_processor_.Initialize(codec->input_channels(), codec->input_reference());
|
|
||||||
audio_processor_.OnOutput([this](std::vector<int16_t>&& data) {
|
|
||||||
Schedule([this, data = std::move(data)]() {
|
|
||||||
if (chat_state_ == kChatStateListening) {
|
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
|
||||||
audio_encode_queue_.emplace_back(std::move(data));
|
|
||||||
cv_.notify_all();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
chat_state_ = kChatStateIdle;
|
chat_state_ = kChatStateIdle;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#define AUDIO_INPUT_SAMPLE_RATE 16000
|
#define AUDIO_INPUT_SAMPLE_RATE 16000
|
||||||
#define AUDIO_OUTPUT_SAMPLE_RATE 16000
|
#define AUDIO_OUTPUT_SAMPLE_RATE 16000
|
||||||
#define AUDIO_DEFAULT_OUTPUT_VOLUME 90
|
#define AUDIO_DEFAULT_OUTPUT_VOLUME 80
|
||||||
|
|
||||||
#define AUDIO_INPUT_REFERENCE true
|
#define AUDIO_INPUT_REFERENCE true
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||||
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
||||||
#define AUDIO_DEFAULT_OUTPUT_VOLUME 90
|
#define AUDIO_DEFAULT_OUTPUT_VOLUME 80
|
||||||
|
|
||||||
#define AUDIO_INPUT_REFERENCE true
|
#define AUDIO_INPUT_REFERENCE true
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public:
|
|||||||
audio_codec = new BoxAudioCodec(i2c_bus_, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
|
audio_codec = new BoxAudioCodec(i2c_bus_, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
|
||||||
AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN,
|
AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN,
|
||||||
GPIO_NUM_NC, AUDIO_CODEC_ES8311_ADDR, AUDIO_CODEC_ES7210_ADDR, AUDIO_INPUT_REFERENCE);
|
GPIO_NUM_NC, AUDIO_CODEC_ES8311_ADDR, AUDIO_CODEC_ES7210_ADDR, AUDIO_INPUT_REFERENCE);
|
||||||
// audio_codec->SetOutputVolume(AUDIO_DEFAULT_OUTPUT_VOLUME);
|
audio_codec->SetOutputVolume(AUDIO_DEFAULT_OUTPUT_VOLUME);
|
||||||
}
|
}
|
||||||
return audio_codec;
|
return audio_codec;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ St7789Display::St7789Display(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_h
|
|||||||
.mirror_y = mirror_y_,
|
.mirror_y = mirror_y_,
|
||||||
},
|
},
|
||||||
.flags = {
|
.flags = {
|
||||||
.buff_dma = 0,
|
.buff_dma = 1,
|
||||||
.buff_spiram = 1,
|
.buff_spiram = 0,
|
||||||
.sw_rotate = 0,
|
.sw_rotate = 0,
|
||||||
.full_refresh = 0,
|
.full_refresh = 0,
|
||||||
.direct_mode = 0,
|
.direct_mode = 0,
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ void Ota::Upgrade(const std::string& firmware_url) {
|
|||||||
size_t total_read = 0, recent_read = 0;
|
size_t total_read = 0, recent_read = 0;
|
||||||
auto last_calc_time = esp_timer_get_time();
|
auto last_calc_time = esp_timer_get_time();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
taskYIELD(); // Avoid watchdog timeout
|
||||||
int ret = http->Read(buffer, sizeof(buffer));
|
int ret = http->Read(buffer, sizeof(buffer));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ESP_LOGE(TAG, "Failed to read HTTP data: %s", esp_err_to_name(ret));
|
ESP_LOGE(TAG, "Failed to read HTTP data: %s", esp_err_to_name(ret));
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ WakeWordDetect::~WakeWordDetect() {
|
|||||||
if (wake_word_encode_task_stack_ != nullptr) {
|
if (wake_word_encode_task_stack_ != nullptr) {
|
||||||
free(wake_word_encode_task_stack_);
|
free(wake_word_encode_task_stack_);
|
||||||
}
|
}
|
||||||
|
if (audio_detection_task_stack_ != nullptr) {
|
||||||
|
heap_caps_free(audio_detection_task_stack_);
|
||||||
|
}
|
||||||
|
|
||||||
vEventGroupDelete(event_group_);
|
vEventGroupDelete(event_group_);
|
||||||
}
|
}
|
||||||
@@ -77,11 +80,13 @@ void WakeWordDetect::Initialize(int channels, bool reference) {
|
|||||||
|
|
||||||
afe_detection_data_ = esp_afe_sr_v1.create_from_config(&afe_config);
|
afe_detection_data_ = esp_afe_sr_v1.create_from_config(&afe_config);
|
||||||
|
|
||||||
xTaskCreate([](void* arg) {
|
const size_t audio_detection_task_stack_size = 4096 * 2;
|
||||||
|
audio_detection_task_stack_ = (StackType_t*)heap_caps_malloc(audio_detection_task_stack_size, MALLOC_CAP_SPIRAM);
|
||||||
|
xTaskCreateStatic([](void* arg) {
|
||||||
auto this_ = (WakeWordDetect*)arg;
|
auto this_ = (WakeWordDetect*)arg;
|
||||||
this_->AudioDetectionTask();
|
this_->AudioDetectionTask();
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}, "audio_detection", 4096 * 2, this, 1, NULL);
|
}, "audio_detection", audio_detection_task_stack_size, this, 1, audio_detection_task_stack_, &audio_detection_task_buffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WakeWordDetect::OnWakeWordDetected(std::function<void()> callback) {
|
void WakeWordDetect::OnWakeWordDetected(std::function<void()> callback) {
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ private:
|
|||||||
int channels_;
|
int channels_;
|
||||||
bool reference_;
|
bool reference_;
|
||||||
|
|
||||||
|
TaskHandle_t audio_detection_task_ = nullptr;
|
||||||
|
StaticTask_t audio_detection_task_buffer_;
|
||||||
|
StackType_t* audio_detection_task_stack_ = nullptr;
|
||||||
|
|
||||||
TaskHandle_t wake_word_encode_task_ = nullptr;
|
TaskHandle_t wake_word_encode_task_ = nullptr;
|
||||||
StaticTask_t wake_word_encode_task_buffer_;
|
StaticTask_t wake_word_encode_task_buffer_;
|
||||||
StackType_t* wake_word_encode_task_stack_ = nullptr;
|
StackType_t* wake_word_encode_task_stack_ = nullptr;
|
||||||
|
|||||||
48
release.py
Normal file
48
release.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def get_board_type():
|
||||||
|
with open("build/compile_commands.json") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
for item in data:
|
||||||
|
if not item["file"].endswith("main.cc"):
|
||||||
|
continue
|
||||||
|
command = item["command"]
|
||||||
|
# extract -DBOARD_TYPE=xxx
|
||||||
|
board_type = command.split("-DBOARD_TYPE=\\\"")[1].split("\\\"")[0].strip()
|
||||||
|
return board_type
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_project_version():
|
||||||
|
with open("CMakeLists.txt") as f:
|
||||||
|
for line in f:
|
||||||
|
if line.startswith("set(PROJECT_VER"):
|
||||||
|
return line.split("\"")[1].split("\"")[0].strip()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def merge_bin():
|
||||||
|
if os.system("idf.py merge-bin") != 0:
|
||||||
|
print("merge bin failed")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def zip_bin(board_type, project_version):
|
||||||
|
if not os.path.exists("releases"):
|
||||||
|
os.makedirs("releases")
|
||||||
|
output_path = f"releases/v{project_version}_{board_type}.zip"
|
||||||
|
if os.path.exists(output_path):
|
||||||
|
os.remove(output_path)
|
||||||
|
if os.system(f"zip -j {output_path} build/merged-binary.bin") != 0:
|
||||||
|
print("zip bin failed")
|
||||||
|
sys.exit(1)
|
||||||
|
print(f"zip bin to {output_path} done")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
merge_bin()
|
||||||
|
board_type = get_board_type()
|
||||||
|
print("board type:", board_type)
|
||||||
|
project_version = get_project_version()
|
||||||
|
print("project version:", project_version)
|
||||||
|
zip_bin(board_type, project_version)
|
||||||
@@ -64,6 +64,8 @@ def get_board_name(folder):
|
|||||||
return "bread-compact-wifi"
|
return "bread-compact-wifi"
|
||||||
elif "KevinBox1" in basename:
|
elif "KevinBox1" in basename:
|
||||||
return "kevin-box-1"
|
return "kevin-box-1"
|
||||||
|
if basename.startswith("v0.7"):
|
||||||
|
return basename.split("_")[1]
|
||||||
raise Exception(f"Unknown board name: {basename}")
|
raise Exception(f"Unknown board name: {basename}")
|
||||||
|
|
||||||
def read_binary(dir_path):
|
def read_binary(dir_path):
|
||||||
|
|||||||
Reference in New Issue
Block a user