diff --git a/esphome/components/audio_dac/audio_dac.h b/esphome/components/audio_dac/audio_dac.h index 16a422f4ac..aebdd85540 100644 --- a/esphome/components/audio_dac/audio_dac.h +++ b/esphome/components/audio_dac/audio_dac.h @@ -14,6 +14,10 @@ class AudioDac { virtual bool is_muted() = 0; virtual float volume() = 0; + /// Called from the main loop by the speaker driving this DAC once its audio clocks are running. + /// DACs that can only be configured while clocked (e.g. DSP state lost across clock stops) override this. + virtual void on_audio_started() {} + protected: bool is_muted_{false}; }; diff --git a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp index cb82b09f33..7ae58b3e44 100644 --- a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +++ b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp @@ -77,6 +77,12 @@ void I2SAudioSpeakerBase::loop() { ESP_LOGV(TAG, "Started"); xEventGroupClearBits(this->event_group_, SpeakerEventGroupBits::TASK_RUNNING); this->state_ = speaker::STATE_RUNNING; +#ifdef USE_AUDIO_DAC + // The task raises TASK_RUNNING only after enabling the channel, so the clocks are already running + if (this->audio_dac_ != nullptr) { + this->audio_dac_->on_audio_started(); + } +#endif // USE_AUDIO_DAC } if (event_group_bits & SpeakerEventGroupBits::TASK_STOPPING) { ESP_LOGV(TAG, "Stopping");