ESPHome  2024.9.0
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 
7 namespace esphome {
8 namespace i2s_audio {
9 
10 static const char *const TAG = "audio";
11 
14  if (call.get_announcement().has_value()) {
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 }
115 void 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_) {
129  case I2S_STATE_STARTING:
130  this->start_();
131  break;
132  case I2S_STATE_RUNNING:
133  this->play_();
134  break;
135  case I2S_STATE_STOPPING:
136  this->stop_();
137  break;
138  case I2S_STATE_STOPPED:
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
virtual void digital_write(bool value)=0
value_type const & value() const
Definition: optional.h:89
void control(const media_player::MediaPlayerCall &call) override
bool is_failed() const
Definition: component.cpp:143
media_player::MediaPlayerTraits get_traits() override
bool has_value() const
Definition: optional.h:87
virtual void setup()=0
const optional< float > & get_volume() const
Definition: media_player.h:77
void start()
Start running the loop continuously.
Definition: helpers.cpp:648
const optional< bool > & get_announcement() const
Definition: media_player.h:78
void stop()
Stop running the loop continuously.
Definition: helpers.cpp:654
const optional< MediaPlayerCommand > & get_command() const
Definition: media_player.h:75
const optional< std::string > & get_media_url() const
Definition: media_player.h:76
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_volume_(float volume, bool publish=true)