ESPHome 2025.8.0b2
Loading...
Searching...
No Matches
i2s_audio_media_player.cpp
Go to the documentation of this file.
2
3#ifdef USE_ESP32_FRAMEWORK_ARDUINO
4
5#include "esphome/core/log.h"
6
7namespace esphome {
8namespace i2s_audio {
9
10static const char *const TAG = "audio";
11
14 if (call.get_announcement().has_value()) {
15 play_state = call.get_announcement().value() ? media_player::MEDIA_PLAYER_STATE_ANNOUNCING
17 }
18 if (call.get_media_url().has_value()) {
19 this->current_url_ = call.get_media_url();
20 if (this->i2s_state_ != I2S_STATE_STOPPED && this->audio_ != nullptr) {
21 if (this->audio_->isRunning()) {
22 this->audio_->stopSong();
23 }
24 this->audio_->connecttohost(this->current_url_.value().c_str());
25 this->state = play_state;
26 } else {
27 this->start();
28 }
29 }
30
32 this->is_announcement_ = true;
33 }
34
35 if (call.get_volume().has_value()) {
36 this->volume = call.get_volume().value();
37 this->set_volume_(volume);
38 this->unmute_();
39 }
40 if (call.get_command().has_value()) {
41 switch (call.get_command().value()) {
43 this->mute_();
44 break;
46 this->unmute_();
47 break;
49 float new_volume = this->volume + 0.1f;
50 if (new_volume > 1.0f)
51 new_volume = 1.0f;
52 this->set_volume_(new_volume);
53 this->unmute_();
54 break;
55 }
57 float new_volume = this->volume - 0.1f;
58 if (new_volume < 0.0f)
59 new_volume = 0.0f;
60 this->set_volume_(new_volume);
61 this->unmute_();
62 break;
63 }
64 default:
65 break;
66 }
67 if (this->i2s_state_ != I2S_STATE_RUNNING) {
68 return;
69 }
70 switch (call.get_command().value()) {
72 if (!this->audio_->isRunning())
73 this->audio_->pauseResume();
74 this->state = play_state;
75 break;
77 if (this->audio_->isRunning())
78 this->audio_->pauseResume();
80 break;
82 this->stop();
83 break;
85 this->audio_->pauseResume();
86 if (this->audio_->isRunning()) {
88 } else {
90 }
91 break;
92 default:
93 break;
94 }
95 }
96 this->publish_state();
97}
98
100 if (this->mute_pin_ != nullptr) {
101 this->mute_pin_->digital_write(true);
102 } else {
103 this->set_volume_(0.0f, false);
104 }
105 this->muted_ = true;
106}
108 if (this->mute_pin_ != nullptr) {
109 this->mute_pin_->digital_write(false);
110 } else {
111 this->set_volume_(this->volume, false);
112 }
113 this->muted_ = false;
114}
115void I2SAudioMediaPlayer::set_volume_(float volume, bool publish) {
116 if (this->audio_ != nullptr)
117 this->audio_->setVolume(remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 21));
118 if (publish)
119 this->volume = volume;
120}
121
123
125 switch (this->i2s_state_) {
127 this->start_();
128 break;
130 this->play_();
131 break;
133 this->stop_();
134 break;
136 break;
137 }
138}
139
141 this->audio_->loop();
144 !this->audio_->isRunning()) {
145 this->stop();
146 }
147}
148
151 if (!this->parent_->try_lock()) {
152 return; // Waiting for another i2s to return lock
153 }
154
155#if SOC_I2S_SUPPORTS_DAC
156 if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
157 this->audio_ = make_unique<Audio>(true, this->internal_dac_mode_, this->parent_->get_port());
158 } else {
159#endif
160 this->audio_ = make_unique<Audio>(false, 3, this->parent_->get_port());
161
162 i2s_pin_config_t pin_config = this->parent_->get_pin_config();
163 pin_config.data_out_num = this->dout_pin_;
164 i2s_set_pin(this->parent_->get_port(), &pin_config);
165
166 this->audio_->setI2SCommFMT_LSB(this->i2s_comm_fmt_lsb_);
167 this->audio_->forceMono(this->external_dac_channels_ == 1);
168 if (this->mute_pin_ != nullptr) {
169 this->mute_pin_->setup();
170 this->mute_pin_->digital_write(false);
171 }
172#if SOC_I2S_SUPPORTS_DAC
173 }
174#endif
175
177 this->high_freq_.start();
178 this->audio_->setVolume(remap<uint8_t, float>(this->volume, 0.0f, 1.0f, 0, 21));
179 if (this->current_url_.has_value()) {
180 this->audio_->connecttohost(this->current_url_.value().c_str());
182 if (this->is_announcement_) {
184 }
185 this->publish_state();
186 }
187}
189 if (this->i2s_state_ == I2S_STATE_STOPPED) {
190 return;
191 }
192 if (this->i2s_state_ == I2S_STATE_STARTING) {
194 return;
195 }
197}
199 if (this->audio_->isRunning()) {
200 this->audio_->stopSong();
201 return;
202 }
203
204 this->audio_ = nullptr;
205 this->current_url_ = {};
206 this->parent_->unlock();
208
209 this->high_freq_.stop();
211 this->publish_state();
212 this->is_announcement_ = false;
213}
214
216 auto traits = media_player::MediaPlayerTraits();
217 traits.set_supports_pause(true);
218 return traits;
219};
220
222 ESP_LOGCONFIG(TAG, "Audio:");
223 if (this->is_failed()) {
224 ESP_LOGCONFIG(TAG, "Audio failed to initialize!");
225 return;
226 }
227#if SOC_I2S_SUPPORTS_DAC
228 if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
229 switch (this->internal_dac_mode_) {
230 case I2S_DAC_CHANNEL_LEFT_EN:
231 ESP_LOGCONFIG(TAG, " Internal DAC mode: Left");
232 break;
233 case I2S_DAC_CHANNEL_RIGHT_EN:
234 ESP_LOGCONFIG(TAG, " Internal DAC mode: Right");
235 break;
236 case I2S_DAC_CHANNEL_BOTH_EN:
237 ESP_LOGCONFIG(TAG, " Internal DAC mode: Left & Right");
238 break;
239 default:
240 break;
241 }
242 } else {
243#endif
244 ESP_LOGCONFIG(TAG,
245 " External DAC channels: %d\n"
246 " I2S DOUT Pin: %d",
247 this->external_dac_channels_, this->dout_pin_);
248 LOG_PIN(" Mute Pin: ", this->mute_pin_);
249#if SOC_I2S_SUPPORTS_DAC
250 }
251#endif
252}
253
254} // namespace i2s_audio
255} // namespace esphome
256
257#endif // USE_ESP32_FRAMEWORK_ARDUINO
bool is_failed() const
virtual void setup()=0
virtual void digital_write(bool value)=0
void stop()
Stop running the loop continuously.
Definition helpers.cpp:570
void start()
Start running the loop continuously.
Definition helpers.cpp:564
media_player::MediaPlayerTraits get_traits() override
void control(const media_player::MediaPlayerCall &call) override
void set_volume_(float volume, bool publish=true)
const optional< std::string > & get_media_url() const
const optional< MediaPlayerCommand > & get_command() const
const optional< float > & get_volume() const
bool has_value() const
Definition optional.h:92
value_type const & value() const
Definition optional.h:94
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
T remap(U value, U min, U max, T min_out, T max_out)
Remap value from the range (min, max) to (min_out, max_out).
Definition helpers.h:144