mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 00:31:58 +00:00
[speaker] Replace set_retry with set_interval to avoid heap allocation
set_retry internally does a std::make_shared<RetryArgs>() heap allocation on every invocation. Replace with set_interval + countdown counter which avoids this entirely. All 3 call sites used fixed-interval polling (no backoff), making set_interval a direct fit.
This commit is contained in:
@@ -103,6 +103,20 @@ void SpeakerMediaPlayer::set_playlist_delay_ms(AudioPipelineType pipeline_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpeakerMediaPlayer::stop_and_unpause_media_() {
|
||||||
|
this->media_pipeline_->stop();
|
||||||
|
this->unpause_media_remaining_ = 3;
|
||||||
|
this->set_interval("unpause_med", 50, [this]() {
|
||||||
|
if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
|
||||||
|
this->cancel_interval("unpause_med");
|
||||||
|
this->media_pipeline_->set_pause_state(false);
|
||||||
|
this->is_paused_ = false;
|
||||||
|
} else if (--this->unpause_media_remaining_ == 0) {
|
||||||
|
this->cancel_interval("unpause_med");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SpeakerMediaPlayer::watch_media_commands_() {
|
void SpeakerMediaPlayer::watch_media_commands_() {
|
||||||
if (!this->is_ready()) {
|
if (!this->is_ready()) {
|
||||||
return;
|
return;
|
||||||
@@ -144,15 +158,7 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
|||||||
if (this->is_paused_) {
|
if (this->is_paused_) {
|
||||||
// If paused, stop the media pipeline and unpause it after confirming its stopped. This avoids playing a
|
// If paused, stop the media pipeline and unpause it after confirming its stopped. This avoids playing a
|
||||||
// short segment of the paused file before starting the new one.
|
// short segment of the paused file before starting the new one.
|
||||||
this->media_pipeline_->stop();
|
this->stop_and_unpause_media_();
|
||||||
this->set_retry("unpause_med", 50, 3, [this](const uint8_t remaining_attempts) {
|
|
||||||
if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
|
|
||||||
this->media_pipeline_->set_pause_state(false);
|
|
||||||
this->is_paused_ = false;
|
|
||||||
return RetryResult::DONE;
|
|
||||||
}
|
|
||||||
return RetryResult::RETRY;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// Not paused, just directly start the file
|
// Not paused, just directly start the file
|
||||||
if (media_command.file.has_value()) {
|
if (media_command.file.has_value()) {
|
||||||
@@ -197,27 +203,21 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
|||||||
this->cancel_timeout("next_ann");
|
this->cancel_timeout("next_ann");
|
||||||
this->announcement_playlist_.clear();
|
this->announcement_playlist_.clear();
|
||||||
this->announcement_pipeline_->stop();
|
this->announcement_pipeline_->stop();
|
||||||
this->set_retry("unpause_ann", 50, 3, [this](const uint8_t remaining_attempts) {
|
this->unpause_announcement_remaining_ = 3;
|
||||||
|
this->set_interval("unpause_ann", 50, [this]() {
|
||||||
if (this->announcement_pipeline_state_ == AudioPipelineState::STOPPED) {
|
if (this->announcement_pipeline_state_ == AudioPipelineState::STOPPED) {
|
||||||
|
this->cancel_interval("unpause_ann");
|
||||||
this->announcement_pipeline_->set_pause_state(false);
|
this->announcement_pipeline_->set_pause_state(false);
|
||||||
return RetryResult::DONE;
|
} else if (--this->unpause_announcement_remaining_ == 0) {
|
||||||
|
this->cancel_interval("unpause_ann");
|
||||||
}
|
}
|
||||||
return RetryResult::RETRY;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this->media_pipeline_ != nullptr) {
|
if (this->media_pipeline_ != nullptr) {
|
||||||
this->cancel_timeout("next_media");
|
this->cancel_timeout("next_media");
|
||||||
this->media_playlist_.clear();
|
this->media_playlist_.clear();
|
||||||
this->media_pipeline_->stop();
|
this->stop_and_unpause_media_();
|
||||||
this->set_retry("unpause_med", 50, 3, [this](const uint8_t remaining_attempts) {
|
|
||||||
if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
|
|
||||||
this->media_pipeline_->set_pause_state(false);
|
|
||||||
this->is_paused_ = false;
|
|
||||||
return RetryResult::DONE;
|
|
||||||
}
|
|
||||||
return RetryResult::RETRY;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ class SpeakerMediaPlayer : public Component,
|
|||||||
/// media pipelines are defined.
|
/// media pipelines are defined.
|
||||||
inline bool single_pipeline_() { return (this->media_speaker_ == nullptr); }
|
inline bool single_pipeline_() { return (this->media_speaker_ == nullptr); }
|
||||||
|
|
||||||
|
/// Stops the media pipeline and polls until stopped to unpause it, avoiding an audible glitch.
|
||||||
|
void stop_and_unpause_media_();
|
||||||
|
|
||||||
// Processes commands from media_control_command_queue_.
|
// Processes commands from media_control_command_queue_.
|
||||||
void watch_media_commands_();
|
void watch_media_commands_();
|
||||||
|
|
||||||
@@ -141,6 +144,8 @@ class SpeakerMediaPlayer : public Component,
|
|||||||
|
|
||||||
bool is_paused_{false};
|
bool is_paused_{false};
|
||||||
bool is_muted_{false};
|
bool is_muted_{false};
|
||||||
|
uint8_t unpause_media_remaining_{0};
|
||||||
|
uint8_t unpause_announcement_remaining_{0};
|
||||||
|
|
||||||
// The amount to change the volume on volume up/down commands
|
// The amount to change the volume on volume up/down commands
|
||||||
float volume_increment_;
|
float volume_increment_;
|
||||||
|
|||||||
Reference in New Issue
Block a user