ESPHome 2025.5.0
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 ESP_LOGCONFIG(TAG, "Setting up Audio...");
125}
126
128 switch (this->i2s_state_) {
130 this->start_();
131 break;
133 this->play_();
134 break;
136 this->stop_();
137 break;
139 break;
140 }
141}
142
144 this->audio_->loop();
147 !this->audio_->isRunning()) {
148 this->stop();
149 }
150}
151
154 if (!this->parent_->try_lock()) {
155 return; // Waiting for another i2s to return lock
156 }
157
158#if SOC_I2S_SUPPORTS_DAC
159 if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
160 this->audio_ = make_unique<Audio>(true, this->internal_dac_mode_, this->parent_->get_port());
161 } else {
162#endif
163 this->audio_ = make_unique<Audio>(false, 3, this->parent_->get_port());
164
165 i2s_pin_config_t pin_config = this->parent_->get_pin_config();
166 pin_config.data_out_num = this->dout_pin_;
167 i2s_set_pin(this->parent_->get_port(), &pin_config);
168
169 this->audio_->setI2SCommFMT_LSB(this->i2s_comm_fmt_lsb_);
170 this->audio_->forceMono(this->external_dac_channels_ == 1);
171 if (this->mute_pin_ != nullptr) {
172 this->mute_pin_->setup();
173 this->mute_pin_->digital_write(false);
174 }
175#if SOC_I2S_SUPPORTS_DAC
176 }
177#endif
178
180 this->high_freq_.start();
181 this->audio_->setVolume(remap<uint8_t, float>(this->volume, 0.0f, 1.0f, 0, 21));
182 if (this->current_url_.has_value()) {
183 this->audio_->connecttohost(this->current_url_.value().c_str());
185 if (this->is_announcement_) {
187 }
188 this->publish_state();
189 }
190}
192 if (this->i2s_state_ == I2S_STATE_STOPPED) {
193 return;
194 }
195 if (this->i2s_state_ == I2S_STATE_STARTING) {
197 return;
198 }
200}
202 if (this->audio_->isRunning()) {
203 this->audio_->stopSong();
204 return;
205 }
206
207 this->audio_ = nullptr;
208 this->current_url_ = {};
209 this->parent_->unlock();
211
212 this->high_freq_.stop();
214 this->publish_state();
215 this->is_announcement_ = false;
216}
217
219 auto traits = media_player::MediaPlayerTraits();
220 traits.set_supports_pause(true);
221 return traits;
222};
223
225 ESP_LOGCONFIG(TAG, "Audio:");
226 if (this->is_failed()) {
227 ESP_LOGCONFIG(TAG, "Audio failed to initialize!");
228 return;
229 }
230#if SOC_I2S_SUPPORTS_DAC
231 if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
232 switch (this->internal_dac_mode_) {
233 case I2S_DAC_CHANNEL_LEFT_EN:
234 ESP_LOGCONFIG(TAG, " Internal DAC mode: Left");
235 break;
236 case I2S_DAC_CHANNEL_RIGHT_EN:
237 ESP_LOGCONFIG(TAG, " Internal DAC mode: Right");
238 break;
239 case I2S_DAC_CHANNEL_BOTH_EN:
240 ESP_LOGCONFIG(TAG, " Internal DAC mode: Left & Right");
241 break;
242 default:
243 break;
244 }
245 } else {
246#endif
247 ESP_LOGCONFIG(TAG, " External DAC channels: %d", this->external_dac_channels_);
248 ESP_LOGCONFIG(TAG, " I2S DOUT Pin: %d", this->dout_pin_);
249 LOG_PIN(" Mute Pin: ", this->mute_pin_);
250#if SOC_I2S_SUPPORTS_DAC
251 }
252#endif
253}
254
255} // namespace i2s_audio
256} // namespace esphome
257
258#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:679
void start()
Start running the loop continuously.
Definition helpers.cpp:673
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:87
value_type const & value() const
Definition optional.h:89
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::unique_ptr< T > make_unique(Args &&...args)
Definition helpers.h:85
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:162