diff --git a/main/application.cc b/main/application.cc index dc212fd..e78370f 100644 --- a/main/application.cc +++ b/main/application.cc @@ -531,10 +531,25 @@ void Application::Start() { opus_encoder_->Encode(std::move(data), [this](std::vector&& opus) { AudioStreamPacket packet; packet.payload = std::move(opus); - packet.timestamp = last_output_timestamp_; - last_output_timestamp_ = 0; - Schedule([this, packet = std::move(packet)]() { + uint32_t last_output_timestamp_value = last_output_timestamp_.load(); + { + std::lock_guard lock(timestamp_mutex_); + if (!timestamp_queue_.empty()) { + packet.timestamp = timestamp_queue_.front(); + timestamp_queue_.pop_front(); + } else { + packet.timestamp = 0; + } + + if (timestamp_queue_.size() > 3) { // 限制队列长度3 + timestamp_queue_.pop_front(); // 该包发送前先出队保持队列长度 + return; + } + } + Schedule([this, last_output_timestamp_value, packet = std::move(packet)]() { protocol_->SendAudio(packet); + // ESP_LOGI(TAG, "Send %zu bytes, timestamp %lu, last_ts %lu, qsize %zu", + // packet.payload.size(), packet.timestamp, last_output_timestamp_value, timestamp_queue_.size()); }); }); }); @@ -717,7 +732,11 @@ void Application::OnAudioOutput() { pcm = std::move(resampled); } codec->OutputData(pcm); - last_output_timestamp_ = packet.timestamp; + { + std::lock_guard lock(timestamp_mutex_); + timestamp_queue_.push_back(packet.timestamp); + last_output_timestamp_ = packet.timestamp; + } last_output_time_ = std::chrono::steady_clock::now(); }); } @@ -816,6 +835,7 @@ void Application::SetDeviceState(DeviceState state) { display->SetStatus(Lang::Strings::STANDBY); display->SetEmotion("neutral"); audio_processor_->Stop(); + #if CONFIG_USE_WAKE_WORD_DETECT wake_word_detect_.StartDetection(); #endif @@ -824,11 +844,12 @@ void Application::SetDeviceState(DeviceState state) { display->SetStatus(Lang::Strings::CONNECTING); display->SetEmotion("neutral"); display->SetChatMessage("system", ""); + timestamp_queue_.clear(); + last_output_timestamp_ = 0; break; case kDeviceStateListening: display->SetStatus(Lang::Strings::LISTENING); display->SetEmotion("neutral"); - // Update the IoT states before sending the start listening command UpdateIotStates(); @@ -870,7 +891,6 @@ void Application::ResetDecoder() { audio_decode_queue_.clear(); audio_decode_cv_.notify_all(); last_output_time_ = std::chrono::steady_clock::now(); - auto codec = Board::GetInstance().GetAudioCodec(); codec->EnableOutput(true); } diff --git a/main/application.h b/main/application.h index 12cd7f7..7dd3240 100644 --- a/main/application.h +++ b/main/application.h @@ -104,10 +104,14 @@ private: TaskHandle_t audio_loop_task_handle_ = nullptr; BackgroundTask* background_task_ = nullptr; std::chrono::steady_clock::time_point last_output_time_; - std::atomic last_output_timestamp_ = 0; std::list audio_decode_queue_; std::condition_variable audio_decode_cv_; + // 新增:用于维护音频包的timestamp队列 + std::list timestamp_queue_; + std::mutex timestamp_mutex_; + std::atomic last_output_timestamp_ = 0; + std::unique_ptr opus_encoder_; std::unique_ptr opus_decoder_;