add abort command

This commit is contained in:
Terrence
2024-10-31 05:57:13 +08:00
parent 6f5f5a0642
commit a701d5918e
4 changed files with 29 additions and 17 deletions

View File

@@ -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.6.0") set(PROJECT_VER "0.6.1")
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(xiaozhi) project(xiaozhi)

View File

@@ -230,7 +230,7 @@ void Application::Start() {
SetChatState(kChatStateIdle); SetChatState(kChatStateIdle);
} }
} else if (chat_state_ == kChatStateSpeaking) { } else if (chat_state_ == kChatStateSpeaking) {
break_speaking_ = true; AbortSpeaking();
} }
// Resume detection // Resume detection
@@ -272,7 +272,7 @@ void Application::Start() {
SetChatState(kChatStateIdle); SetChatState(kChatStateIdle);
} }
} else if (chat_state_ == kChatStateSpeaking) { } else if (chat_state_ == kChatStateSpeaking) {
break_speaking_ = true; AbortSpeaking();
} else if (chat_state_ == kChatStateListening) { } else if (chat_state_ == kChatStateListening) {
if (ws_client_ && ws_client_->IsConnected()) { if (ws_client_ && ws_client_->IsConnected()) {
ws_client_->Close(); ws_client_->Close();
@@ -356,6 +356,22 @@ void Application::MainLoop() {
} }
} }
void Application::AbortSpeaking() {
ESP_LOGI(TAG, "Abort speaking");
skip_to_end_ = true;
if (ws_client_ && ws_client_->IsConnected()) {
cJSON* root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "type", "abort");
char* json = cJSON_PrintUnformatted(root);
std::lock_guard<std::mutex> lock(mutex_);
ws_client_->Send(json);
cJSON_Delete(root);
free(json);
}
}
void Application::SetChatState(ChatState state) { void Application::SetChatState(ChatState state) {
const char* state_str[] = { const char* state_str[] = {
"unknown", "unknown",
@@ -368,6 +384,10 @@ void Application::SetChatState(ChatState state) {
"upgrading", "upgrading",
"invalid_state" "invalid_state"
}; };
if (chat_state_ == state) {
// No need to update the state
return;
}
chat_state_ = state; chat_state_ = state;
ESP_LOGI(TAG, "STATE: %s", state_str[chat_state_]); ESP_LOGI(TAG, "STATE: %s", state_str[chat_state_]);
@@ -488,16 +508,6 @@ void Application::HandleAudioPacket(AudioPacket* packet) {
// This will block until the audio device has finished playing the audio // This will block until the audio device has finished playing the audio
audio_device_->OutputData(packet->pcm); audio_device_->OutputData(packet->pcm);
if (break_speaking_) {
skip_to_end_ = true;
// Play a silence and skip to the end
int frame_size = opus_decode_sample_rate_ / 1000 * opus_duration_ms_;
std::vector<int16_t> silence(frame_size);
bzero(silence.data(), silence.size() * sizeof(int16_t));
audio_device_->OutputData(silence);
}
break; break;
} }
case kAudioPacketTypeStart: case kAudioPacketTypeStart:
@@ -520,6 +530,9 @@ void Application::HandleAudioPacket(AudioPacket* packet) {
ESP_LOGI(TAG, "<< %s", packet->text.c_str()); ESP_LOGI(TAG, "<< %s", packet->text.c_str());
break; break;
case kAudioPacketTypeSentenceEnd: case kAudioPacketTypeSentenceEnd:
if (break_speaking_) {
skip_to_end_ = true;
}
break; break;
default: default:
ESP_LOGI(TAG, "Unknown packet type: %d", packet->type); ESP_LOGI(TAG, "Unknown packet type: %d", packet->type);
@@ -622,8 +635,7 @@ void Application::StartWebSocketClient() {
SetDecodeSampleRate(sample_rate->valueint); SetDecodeSampleRate(sample_rate->valueint);
} }
// If the device is speaking, we need to break the speaking // If the device is speaking, we need to skip the last session
break_speaking_ = true;
skip_to_end_ = true; skip_to_end_ = true;
} else if (strcmp(state->valuestring, "stop") == 0) { } else if (strcmp(state->valuestring, "stop") == 0) {
packet->type = kAudioPacketTypeStop; packet->type = kAudioPacketTypeStop;

View File

@@ -77,7 +77,7 @@ public:
void Schedule(std::function<void()> callback); void Schedule(std::function<void()> callback);
void SetChatState(ChatState state); void SetChatState(ChatState state);
void Alert(const std::string&& title, const std::string&& message); void Alert(const std::string&& title, const std::string&& message);
void AbortSpeaking();
// 删除拷贝构造函数和赋值运算符 // 删除拷贝构造函数和赋值运算符
Application(const Application&) = delete; Application(const Application&) = delete;
Application& operator=(const Application&) = delete; Application& operator=(const Application&) = delete;

View File

@@ -95,7 +95,7 @@ void AudioDevice::CreateSimplexChannels() {
.role = I2S_ROLE_MASTER, .role = I2S_ROLE_MASTER,
.dma_desc_num = 6, .dma_desc_num = 6,
.dma_frame_num = 240, .dma_frame_num = 240,
.auto_clear_after_cb = false, .auto_clear_after_cb = true,
.auto_clear_before_cb = false, .auto_clear_before_cb = false,
.intr_priority = 0, .intr_priority = 0,
}; };