fix(control_plane): serialize wake prompt after barge-in
This commit is contained in:
@@ -43,6 +43,8 @@
|
||||
|
||||
#define CONTROL_PLANE_LOCAL_WAKE_QUEUE_LEN 4U
|
||||
#define CONTROL_PLANE_LOCAL_WAKE_POLL_MS 100U
|
||||
#define CONTROL_PLANE_LOCAL_WAKE_BARGE_IN_WAIT_MS 2000U
|
||||
#define CONTROL_PLANE_LOCAL_WAKE_BARGE_IN_POLL_MS 20U
|
||||
|
||||
#if CONFIG_TQ_LOCAL_WAKE_TASK_CORE < 0
|
||||
#define CONTROL_PLANE_LOCAL_WAKE_TASK_CORE tskNO_AFFINITY
|
||||
@@ -151,6 +153,64 @@ static esp_err_t local_wake_start_listening(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_TQ_LOCAL_WAKE_RESPONSE_PROMPT_ENABLE
|
||||
static bool local_wake_prepare_prompt_playback(void)
|
||||
{
|
||||
control_plane_multimodal_runtime_state_t state = {0};
|
||||
esp_err_t state_err = control_plane_multimodal_get_runtime_state(&state);
|
||||
if (state_err != ESP_OK) {
|
||||
ESP_LOGW(TAG,
|
||||
"Skip local wake prompt: runtime state unavailable: %s",
|
||||
esp_err_to_name(state_err));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!state.remote_responding && !state.request_to_speak_pending) {
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t request_err = control_plane_multimodal_send_request_to_speak();
|
||||
if (request_err != ESP_OK && request_err != ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG,
|
||||
"Skip local wake prompt: barge-in request failed: %s",
|
||||
esp_err_to_name(request_err));
|
||||
return false;
|
||||
}
|
||||
|
||||
TickType_t started = xTaskGetTickCount();
|
||||
TickType_t timeout_ticks = pdMS_TO_TICKS(
|
||||
CONTROL_PLANE_LOCAL_WAKE_BARGE_IN_WAIT_MS);
|
||||
if (timeout_ticks == 0U) {
|
||||
timeout_ticks = 1U;
|
||||
}
|
||||
|
||||
while ((xTaskGetTickCount() - started) < timeout_ticks) {
|
||||
local_wake_state_t wake_state = local_wake_snapshot();
|
||||
if (wake_state.stop_requested) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state_err = control_plane_multimodal_get_runtime_state(&state);
|
||||
if (state_err == ESP_OK) {
|
||||
if (!state.connected || !state.has_active_task) {
|
||||
return false;
|
||||
}
|
||||
if (!state.remote_responding &&
|
||||
!state.request_to_speak_pending &&
|
||||
state.server_listening) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_LOCAL_WAKE_BARGE_IN_POLL_MS));
|
||||
}
|
||||
|
||||
ESP_LOGW(TAG,
|
||||
"Skip local wake prompt: barge-in confirmation timed out after %ums",
|
||||
(unsigned)CONTROL_PLANE_LOCAL_WAKE_BARGE_IN_WAIT_MS);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void local_wake_handle_detection(
|
||||
const domain_local_command_event_t *event)
|
||||
{
|
||||
@@ -178,7 +238,9 @@ static void local_wake_handle_detection(
|
||||
(unsigned)event->detection_generation);
|
||||
|
||||
#if CONFIG_TQ_LOCAL_WAKE_RESPONSE_PROMPT_ENABLE
|
||||
if (CONFIG_TQ_LOCAL_WAKE_RESPONSE_PROMPT_FILE[0] != '\0') {
|
||||
bool prompt_playback_ready = local_wake_prepare_prompt_playback();
|
||||
if (prompt_playback_ready &&
|
||||
CONFIG_TQ_LOCAL_WAKE_RESPONSE_PROMPT_FILE[0] != '\0') {
|
||||
esp_err_t prompt_err = domain_runtime_behavior_play_prompt_file(
|
||||
CONFIG_TQ_LOCAL_WAKE_RESPONSE_PROMPT_FILE);
|
||||
if (prompt_err != ESP_OK) {
|
||||
|
||||
@@ -1336,6 +1336,7 @@ static void process_text_json(const char *json_text)
|
||||
notify_event(CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_NOT_LISTENING);
|
||||
}
|
||||
} else if (strcmp(output_event->valuestring, "RequestAccepted") == 0) {
|
||||
stop_local_downstream_playback();
|
||||
if (lock_state()) {
|
||||
s_server_listening = true;
|
||||
s_remote_responding = false;
|
||||
@@ -1346,7 +1347,6 @@ static void process_text_json(const char *json_text)
|
||||
s_drop_downstream_audio = false;
|
||||
unlock_state();
|
||||
}
|
||||
stop_local_downstream_playback();
|
||||
ESP_LOGI(TAG, "PTT barge-in request accepted");
|
||||
notify_event(CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_LISTENING);
|
||||
} else if (strcmp(output_event->valuestring, "RespondingStarted") == 0) {
|
||||
|
||||
Reference in New Issue
Block a user