5 #include <driver/i2s.h> 14 static const size_t BUFFER_COUNT = 20;
16 static const char *
const TAG =
"i2s_audio.speaker";
19 ESP_LOGCONFIG(TAG,
"Setting up I2S Audio Speaker...");
23 ESP_LOGE(TAG,
"Failed to create buffer queue");
30 ESP_LOGE(TAG,
"Failed to create event queue");
38 ESP_LOGE(TAG,
"Cannot start audio, speaker failed to setup");
42 ESP_LOGW(TAG,
"Called start while task has been already created.");
51 if (!this->
parent_->try_lock()) {
60 if (
sizeof(a) ==
sizeof(b) && !repeat) {
61 return reinterpret_cast<const uint8_t *
>(from);
64 for (
size_t i = 0; i <
bytes; i +=
sizeof(a)) {
65 b value =
static_cast<b
>(*from++) << (
sizeof(b) -
sizeof(a)) * 8;
70 bytes *= (
sizeof(b) /
sizeof(a)) * (repeat ? 2 : 1);
71 return reinterpret_cast<const uint8_t *
>(result);
79 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
81 i2s_driver_config_t config = {
82 .mode = (i2s_mode_t) (this_speaker->
i2s_mode_ | I2S_MODE_TX),
85 .channel_format = this_speaker->
channel_,
87 .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
91 .tx_desc_auto_clear =
true,
93 .mclk_multiple = I2S_MCLK_MULTIPLE_256,
96 #if SOC_I2S_SUPPORTS_DAC 98 config.mode = (i2s_mode_t) (config.mode | I2S_MODE_DAC_BUILT_IN);
102 esp_err_t err = i2s_driver_install(this_speaker->
parent_->get_port(), &config, 0,
nullptr);
114 #if SOC_I2S_SUPPORTS_DAC 117 i2s_pin_config_t pin_config = this_speaker->
parent_->get_pin_config();
118 pin_config.data_out_num = this_speaker->
dout_pin_;
120 i2s_set_pin(this_speaker->
parent_->get_port(), &pin_config);
121 #if SOC_I2S_SUPPORTS_DAC 130 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
132 int32_t buffer[BUFFER_SIZE];
135 if (xQueueReceive(this_speaker->
buffer_queue_, &data_event, this_speaker->
timeout_ / portTICK_PERIOD_MS) !=
139 if (data_event.
stop) {
145 const uint8_t *data = data_event.
data;
146 size_t remaining = data_event.
len;
148 case I2S_BITS_PER_SAMPLE_8BIT:
149 case I2S_BITS_PER_SAMPLE_16BIT: {
150 data =
convert_data_format(reinterpret_cast<const int16_t *>(data), reinterpret_cast<int16_t *>(buffer),
151 remaining, this_speaker->
channel_ == I2S_CHANNEL_FMT_ALL_LEFT);
154 case I2S_BITS_PER_SAMPLE_24BIT:
155 case I2S_BITS_PER_SAMPLE_32BIT: {
156 data =
convert_data_format(reinterpret_cast<const int16_t *>(data), reinterpret_cast<int32_t *>(buffer),
157 remaining, this_speaker->
channel_ == I2S_CHANNEL_FMT_ALL_LEFT);
162 while (remaining != 0) {
163 size_t bytes_written;
165 i2s_write(this_speaker->
parent_->get_port(), data, remaining, &bytes_written, (32 / portTICK_PERIOD_MS));
168 if (xQueueSend(this_speaker->
event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
169 ESP_LOGW(TAG,
"Failed to send WARNING event");
173 data += bytes_written;
174 remaining -= bytes_written;
179 if (xQueueSend(this_speaker->
event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
180 ESP_LOGW(TAG,
"Failed to send STOPPING event");
183 i2s_zero_dma_buffer(this_speaker->
parent_->get_port());
185 i2s_driver_uninstall(this_speaker->
parent_->get_port());
188 if (xQueueSend(this_speaker->
event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
189 ESP_LOGW(TAG,
"Failed to send STOPPED event");
216 xQueueSendToFront(this->
buffer_queue_, &data, portMAX_DELAY);
222 if (xQueueReceive(this->
event_queue_, &event, 0) == pdTRUE) {
223 switch (event.
type) {
225 ESP_LOGD(TAG,
"Starting I2S Audio Speaker");
228 ESP_LOGD(TAG,
"Started I2S Audio Speaker");
233 ESP_LOGD(TAG,
"Stopping I2S Audio Speaker");
242 ESP_LOGD(TAG,
"Stopped I2S Audio Speaker");
245 ESP_LOGW(TAG,
"Error writing to I2S: %s", esp_err_to_name(event.
err));
268 ESP_LOGE(TAG,
"Cannot play audio, speaker failed to setup");
274 size_t remaining =
length;
276 while (remaining > 0) {
279 size_t to_send_length = std::min(remaining, BUFFER_SIZE);
280 event.len = to_send_length;
281 memcpy(event.
data, data + index, to_send_length);
285 remaining -= to_send_length;
286 index += to_send_length;
void stop_(bool wait_on_empty)
void status_set_warning(const char *message="unspecified")
i2s_dac_mode_t internal_dac_mode_
TaskHandle_t player_task_handle_
static void player_task(void *params)
QueueHandle_t buffer_queue_
I2SAudioComponent * parent_
i2s_channel_fmt_t channel_
void status_clear_warning()
const uint8_t * convert_data_format(const a *from, b *to, size_t &bytes, bool repeat)
QueueHandle_t event_queue_
size_t play(const uint8_t *data, size_t length) override
i2s_bits_per_sample_t bits_per_sample_
virtual void mark_failed()
Mark this component as failed.
Implementation of SPI Controller mode.
std::vector< uint8_t > bytes
bool has_buffered_data() const override
i2s_bits_per_chan_t bits_per_channel_
uint8_t data[BUFFER_SIZE]
i2s_comm_format_t i2s_comm_fmt_
void IRAM_ATTR HOT delay(uint32_t ms)