From 46d19d82c2df3885690ed3f67a78e95728bafb77 Mon Sep 17 00:00:00 2001 From: Kevin Ahrendt Date: Tue, 11 Feb 2025 12:14:59 -0600 Subject: [PATCH] [speaker] Bugfix: Ensure all audio is played after completely decoding a file (#8231) --- .../components/speaker/media_player/audio_pipeline.cpp | 10 +++++++++- .../components/speaker/media_player/audio_pipeline.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/esphome/components/speaker/media_player/audio_pipeline.cpp b/esphome/components/speaker/media_player/audio_pipeline.cpp index 73ec5a3334..b49cf3ddda 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.cpp +++ b/esphome/components/speaker/media_player/audio_pipeline.cpp @@ -182,13 +182,21 @@ AudioPipelineState AudioPipeline::process_state() { if (event_bits & EventGroupBits::PIPELINE_COMMAND_STOP) { // Stop command is fully processed, so clear the command bit xEventGroupClearBits(this->event_group_, EventGroupBits::PIPELINE_COMMAND_STOP); + this->hard_stop_ = true; } if (!this->is_playing_) { // The tasks have been stopped for two ``process_state`` calls in a row, so delete the tasks if ((this->read_task_handle_ != nullptr) || (this->decode_task_handle_ != nullptr)) { this->delete_tasks_(); - this->speaker_->stop(); + if (this->hard_stop_) { + // Stop command was sent, so immediately end of the playback + this->speaker_->stop(); + this->hard_stop_ = false; + } else { + // Decoded all the audio, so let the speaker finish playing before stopping + this->speaker_->finish(); + } } } this->is_playing_ = false; diff --git a/esphome/components/speaker/media_player/audio_pipeline.h b/esphome/components/speaker/media_player/audio_pipeline.h index c382e1eebe..722d9cbb2a 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.h +++ b/esphome/components/speaker/media_player/audio_pipeline.h @@ -112,6 +112,7 @@ class AudioPipeline { uint32_t playback_ms_{0}; + bool hard_stop_{false}; bool is_playing_{false}; bool pause_state_{false}; bool task_stack_in_psram_;