8#include <driver/i2s_std.h>
22static const uint8_t DMA_BUFFER_DURATION_MS = 15;
23static const size_t DMA_BUFFERS_COUNT = 4;
25static const size_t TASK_DELAY_MS = DMA_BUFFER_DURATION_MS * DMA_BUFFERS_COUNT / 2;
27static const size_t TASK_STACK_SIZE = 4096;
28static const ssize_t TASK_PRIORITY = 23;
30static const size_t I2S_EVENT_QUEUE_COUNT = DMA_BUFFERS_COUNT + 1;
32static const char *
const TAG =
"i2s_audio.speaker";
34enum SpeakerEventGroupBits : uint32_t {
35 COMMAND_START = (1 << 0),
37 COMMAND_STOP_GRACEFULLY = (1 << 2),
38 STATE_STARTING = (1 << 10),
40 STATE_STOPPING = (1 << 12),
42 ERR_TASK_FAILED_TO_START = (1 << 14),
43 ERR_ESP_INVALID_STATE = (1 << 15),
44 ERR_ESP_NOT_SUPPORTED = (1 << 16),
45 ERR_ESP_INVALID_ARG = (1 << 17),
46 ERR_ESP_INVALID_SIZE = (1 << 18),
48 ERR_ESP_FAIL = (1 << 20),
49 ALL_ERR_ESP_BITS = ERR_ESP_INVALID_STATE |
ERR_ESP_NOT_SUPPORTED | ERR_ESP_INVALID_ARG | ERR_ESP_INVALID_SIZE |
55static esp_err_t err_bit_to_esp_err(uint32_t bit) {
57 case SpeakerEventGroupBits::ERR_ESP_INVALID_STATE:
58 return ESP_ERR_INVALID_STATE;
59 case SpeakerEventGroupBits::ERR_ESP_INVALID_ARG:
60 return ESP_ERR_INVALID_ARG;
61 case SpeakerEventGroupBits::ERR_ESP_INVALID_SIZE:
62 return ESP_ERR_INVALID_SIZE;
63 case SpeakerEventGroupBits::ERR_ESP_NO_MEM:
64 return ESP_ERR_NO_MEM;
65 case SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED:
66 return ESP_ERR_NOT_SUPPORTED;
81static void q15_multiplication(
const int16_t *input, int16_t *output,
size_t len, int16_t c) {
82 for (
int i = 0; i <
len; i++) {
83 int32_t acc = (int32_t) input[i] * (int32_t) c;
84 output[i] = (int16_t) (acc >> 15);
92static const std::vector<int16_t> Q15_VOLUME_SCALING_FACTORS = {
93 0, 116, 122, 130, 137, 146, 154, 163, 173, 183, 194, 206, 218, 231, 244,
94 259, 274, 291, 308, 326, 345, 366, 388, 411, 435, 461, 488, 517, 548, 580,
95 615, 651, 690, 731, 774, 820, 868, 920, 974, 1032, 1094, 1158, 1227, 1300, 1377,
96 1459, 1545, 1637, 1734, 1837, 1946, 2061, 2184, 2313, 2450, 2596, 2750, 2913, 3085, 3269,
97 3462, 3668, 3885, 4116, 4360, 4619, 4893, 5183, 5490, 5816, 6161, 6527, 6914, 7324, 7758,
98 8218, 8706, 9222, 9770, 10349, 10963, 11613, 12302, 13032, 13805, 14624, 15491, 16410, 17384, 18415,
99 19508, 20665, 21891, 23189, 24565, 26022, 27566, 29201, 30933, 32767};
102 ESP_LOGCONFIG(TAG,
"Setting up I2S Audio Speaker...");
107 ESP_LOGE(TAG,
"Failed to create event group");
114 uint32_t event_group_bits = xEventGroupGetBits(this->
event_group_);
116 if (event_group_bits & SpeakerEventGroupBits::STATE_STARTING) {
117 ESP_LOGD(TAG,
"Starting Speaker");
119 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_STARTING);
121 if (event_group_bits & SpeakerEventGroupBits::STATE_RUNNING) {
122 ESP_LOGD(TAG,
"Started Speaker");
124 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_RUNNING);
128 if (event_group_bits & SpeakerEventGroupBits::STATE_STOPPING) {
129 ESP_LOGD(TAG,
"Stopping Speaker");
131 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_STOPPING);
133 if (event_group_bits & SpeakerEventGroupBits::STATE_STOPPED) {
135 ESP_LOGD(TAG,
"Stopped Speaker");
137 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::ALL_BITS);
142 if (event_group_bits & SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START) {
144 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START);
147 if (event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS) {
148 uint32_t error_bits = event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS;
149 ESP_LOGW(TAG,
"Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
153 if (event_group_bits & SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED) {
154 this->
status_set_error(
"Failed to adjust I2S bus to match the incoming audio");
156 "Incompatible audio format: sample rate = %" PRIu32
", channels = %" PRIu8
", bits per sample = %" PRIu8,
158 this->audio_stream_info_.get_bits_per_sample());
161 xEventGroupClearBits(this->
event_group_, ALL_ERR_ESP_BITS);
205 ESP_LOGE(TAG,
"Cannot play audio, speaker failed to setup");
214 vTaskDelay(ticks_to_wait);
218 size_t bytes_written = 0;
225 bytes_written = temp_ring_buffer->write_without_replacement((
void *) data,
length, ticks_to_wait);
228 return bytes_written;
239 I2SAudioSpeaker *this_speaker = (I2SAudioSpeaker *) params;
240 this_speaker->task_created_ =
true;
242 uint32_t event_group_bits =
243 xEventGroupWaitBits(this_speaker->event_group_,
244 SpeakerEventGroupBits::COMMAND_START | SpeakerEventGroupBits::COMMAND_STOP |
245 SpeakerEventGroupBits::COMMAND_STOP_GRACEFULLY,
250 if (event_group_bits & (SpeakerEventGroupBits::COMMAND_STOP | SpeakerEventGroupBits::COMMAND_STOP_GRACEFULLY)) {
252 this_speaker->delete_task_(0);
255 xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STARTING);
257 audio::AudioStreamInfo audio_stream_info = this_speaker->audio_stream_info_;
259 const uint32_t dma_buffers_duration_ms = DMA_BUFFER_DURATION_MS * DMA_BUFFERS_COUNT;
261 const uint32_t ring_buffer_duration = std::max(dma_buffers_duration_ms, this_speaker->buffer_duration_ms_);
264 const size_t data_buffer_size = audio_stream_info.ms_to_bytes(dma_buffers_duration_ms);
265 const size_t ring_buffer_size = audio_stream_info.ms_to_bytes(ring_buffer_duration);
267 const size_t single_dma_buffer_input_size = data_buffer_size / DMA_BUFFERS_COUNT;
269 if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(data_buffer_size, ring_buffer_size))) {
271 xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::ERR_ESP_NO_MEM);
272 this_speaker->delete_task_(data_buffer_size);
275 if (!this_speaker->send_esp_err_to_event_group_(this_speaker->start_i2s_driver_(audio_stream_info))) {
276 xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_RUNNING);
278 bool stop_gracefully =
false;
279 uint32_t last_data_received_time =
millis();
280 bool tx_dma_underflow =
false;
282 this_speaker->accumulated_frames_written_ = 0;
286 while (this_speaker->pause_state_ || !this_speaker->timeout_.has_value() ||
287 (
millis() - last_data_received_time) <= this_speaker->timeout_.value()) {
288 event_group_bits = xEventGroupGetBits(this_speaker->event_group_);
290 if (event_group_bits & SpeakerEventGroupBits::COMMAND_STOP) {
291 xEventGroupClearBits(this_speaker->event_group_, SpeakerEventGroupBits::COMMAND_STOP);
294 if (event_group_bits & SpeakerEventGroupBits::COMMAND_STOP_GRACEFULLY) {
295 xEventGroupClearBits(this_speaker->event_group_, SpeakerEventGroupBits::COMMAND_STOP_GRACEFULLY);
296 stop_gracefully =
true;
299 if (this_speaker->audio_stream_info_ != audio_stream_info) {
304 i2s_event_t i2s_event;
305 while (xQueueReceive(this_speaker->i2s_event_queue_, &i2s_event, 0)) {
306 if (i2s_event.type == I2S_EVENT_TX_Q_OVF) {
307 tx_dma_underflow =
true;
312 while (xQueueReceive(this_speaker->i2s_event_queue_, &overflow, 0)) {
314 tx_dma_underflow =
true;
319 if (this_speaker->pause_state_) {
322 delay(TASK_DELAY_MS);
326 size_t bytes_read = this_speaker->audio_ring_buffer_->read((
void *) this_speaker->data_buffer_, data_buffer_size,
327 pdMS_TO_TICKS(TASK_DELAY_MS));
329 if (bytes_read > 0) {
330 if ((audio_stream_info.get_bits_per_sample() == 16) && (this_speaker->q15_volume_factor_ < INT16_MAX)) {
332 q15_multiplication((int16_t *) this_speaker->data_buffer_, (int16_t *) this_speaker->data_buffer_,
333 bytes_read /
sizeof(int16_t), this_speaker->q15_volume_factor_);
336#ifdef USE_ESP32_VARIANT_ESP32
338 if (audio_stream_info.get_channels() == 1 && audio_stream_info.get_bits_per_sample() <= 16) {
339 size_t len = bytes_read /
sizeof(int16_t);
340 int16_t *tmp_buf = (int16_t *) this_speaker->data_buffer_;
341 for (
int i = 0; i <
len; i += 2) {
342 int16_t tmp = tmp_buf[i];
343 tmp_buf[i] = tmp_buf[i + 1];
344 tmp_buf[i + 1] = tmp;
350 const uint32_t batches = (bytes_read + single_dma_buffer_input_size - 1) / single_dma_buffer_input_size;
352 for (uint32_t i = 0; i < batches; ++i) {
353 size_t bytes_written = 0;
354 size_t bytes_to_write = std::min(single_dma_buffer_input_size, bytes_read);
357 if (audio_stream_info.get_bits_per_sample() == (uint8_t) this_speaker->bits_per_sample_) {
358 i2s_write(this_speaker->parent_->get_port(), this_speaker->data_buffer_ + i * single_dma_buffer_input_size,
359 bytes_to_write, &bytes_written, pdMS_TO_TICKS(DMA_BUFFER_DURATION_MS * 5));
360 }
else if (audio_stream_info.get_bits_per_sample() < (uint8_t) this_speaker->bits_per_sample_) {
361 i2s_write_expand(this_speaker->parent_->get_port(),
362 this_speaker->data_buffer_ + i * single_dma_buffer_input_size, bytes_to_write,
363 audio_stream_info.get_bits_per_sample(), this_speaker->bits_per_sample_, &bytes_written,
364 pdMS_TO_TICKS(DMA_BUFFER_DURATION_MS * 5));
367 i2s_channel_write(this_speaker->tx_handle_, this_speaker->data_buffer_ + i * single_dma_buffer_input_size,
368 bytes_to_write, &bytes_written, pdMS_TO_TICKS(DMA_BUFFER_DURATION_MS * 5));
371 int64_t now = esp_timer_get_time();
373 if (bytes_written != bytes_to_write) {
374 xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::ERR_ESP_INVALID_SIZE);
376 bytes_read -= bytes_written;
378 this_speaker->audio_output_callback_(audio_stream_info.bytes_to_frames(bytes_written),
379 now + dma_buffers_duration_ms * 1000);
381 tx_dma_underflow =
false;
382 last_data_received_time =
millis();
386 if (stop_gracefully && tx_dma_underflow) {
392 xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STOPPING);
394 i2s_driver_uninstall(this_speaker->parent_->get_port());
396 i2s_channel_disable(this_speaker->tx_handle_);
397 i2s_del_channel(this_speaker->tx_handle_);
400 this_speaker->parent_->unlock();
403 this_speaker->delete_task_(data_buffer_size);
417 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::COMMAND_START);
419 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START);
435 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::COMMAND_STOP_GRACEFULLY);
437 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::COMMAND_STOP);
445 case ESP_ERR_INVALID_STATE:
446 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_INVALID_STATE);
448 case ESP_ERR_INVALID_ARG:
449 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_INVALID_ARG);
451 case ESP_ERR_INVALID_SIZE:
452 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_INVALID_SIZE);
455 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_NO_MEM);
457 case ESP_ERR_NOT_SUPPORTED:
458 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED);
461 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::ERR_ESP_FAIL);
470 this->
data_buffer_ = allocator.allocate(data_buffer_size);
474 return ESP_ERR_NO_MEM;
483 return ESP_ERR_NO_MEM;
491 if ((this->
i2s_mode_ & I2S_MODE_SLAVE) && (this->
sample_rate_ != audio_stream_info.get_sample_rate())) {
493 if ((this->
i2s_role_ & I2S_ROLE_SLAVE) && (this->
sample_rate_ != audio_stream_info.get_sample_rate())) {
496 return ESP_ERR_NOT_SUPPORTED;
500 if ((i2s_bits_per_sample_t) audio_stream_info.get_bits_per_sample() > this->bits_per_sample_) {
503 (i2s_slot_bit_width_t) audio_stream_info.get_bits_per_sample() > this->slot_bit_width_) {
506 return ESP_ERR_NOT_SUPPORTED;
509 if (!this->
parent_->try_lock()) {
510 return ESP_ERR_INVALID_STATE;
513 uint32_t dma_buffer_length = audio_stream_info.ms_to_frames(DMA_BUFFER_DURATION_MS);
516 i2s_channel_fmt_t channel = this->
channel_;
518 if (audio_stream_info.get_channels() == 1) {
519 if (this->
channel_ == I2S_CHANNEL_FMT_ONLY_LEFT) {
520 channel = I2S_CHANNEL_FMT_ONLY_LEFT;
522 channel = I2S_CHANNEL_FMT_ONLY_RIGHT;
524 }
else if (audio_stream_info.get_channels() == 2) {
525 channel = I2S_CHANNEL_FMT_RIGHT_LEFT;
528 i2s_driver_config_t config = {
529 .mode = (i2s_mode_t) (this->
i2s_mode_ | I2S_MODE_TX),
530 .sample_rate = audio_stream_info.get_sample_rate(),
532 .channel_format = channel,
534 .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
535 .dma_buf_count = DMA_BUFFERS_COUNT,
536 .dma_buf_len = (int) dma_buffer_length,
538 .tx_desc_auto_clear =
true,
539 .fixed_mclk = I2S_PIN_NO_CHANGE,
542#
if SOC_I2S_SUPPORTS_TDM
543 .chan_mask = (i2s_channel_t) (I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1),
547 .bit_order_msb =
false,
551#if SOC_I2S_SUPPORTS_DAC
553 config.mode = (i2s_mode_t) (config.mode | I2S_MODE_DAC_BUILT_IN);
558 i2s_driver_install(this->
parent_->get_port(), &config, I2S_EVENT_QUEUE_COUNT, &this->i2s_event_queue_);
565#if SOC_I2S_SUPPORTS_DAC
568 i2s_pin_config_t pin_config = this->
parent_->get_pin_config();
569 pin_config.data_out_num = this->
dout_pin_;
571 err = i2s_set_pin(this->
parent_->get_port(), &pin_config);
572#if SOC_I2S_SUPPORTS_DAC
580 i2s_driver_uninstall(this->
parent_->get_port());
584 i2s_chan_config_t chan_cfg = {
585 .id = this->
parent_->get_port(),
587 .dma_desc_num = DMA_BUFFERS_COUNT,
588 .dma_frame_num = dma_buffer_length,
592 esp_err_t err = i2s_new_channel(&chan_cfg, &this->
tx_handle_, NULL);
598 i2s_clock_src_t clk_src = I2S_CLK_SRC_DEFAULT;
599#ifdef I2S_CLK_SRC_APLL
601 clk_src = I2S_CLK_SRC_APLL;
604 i2s_std_gpio_config_t pin_config = this->
parent_->get_pin_config();
606 i2s_std_clk_config_t clk_cfg = {
607 .sample_rate_hz = audio_stream_info.get_sample_rate(),
614 if (audio_stream_info.get_channels() == 1) {
615 slot_mode = I2S_SLOT_MODE_MONO;
616 }
else if (audio_stream_info.get_channels() == 2) {
617 slot_mode = I2S_SLOT_MODE_STEREO;
618 slot_mask = I2S_STD_SLOT_BOTH;
621 i2s_std_slot_config_t std_slot_cfg;
624 I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG((i2s_data_bit_width_t) audio_stream_info.get_bits_per_sample(), slot_mode);
627 I2S_STD_PCM_SLOT_DEFAULT_CONFIG((i2s_data_bit_width_t) audio_stream_info.get_bits_per_sample(), slot_mode);
630 I2S_STD_MSB_SLOT_DEFAULT_CONFIG((i2s_data_bit_width_t) audio_stream_info.get_bits_per_sample(), slot_mode);
632#ifdef USE_ESP32_VARIANT_ESP32
642 std_slot_cfg.slot_mask = slot_mask;
646 i2s_std_config_t std_cfg = {
648 .slot_cfg = std_slot_cfg,
649 .gpio_cfg = pin_config,
652 err = i2s_channel_init_std_mode(this->
tx_handle_, &std_cfg);
662 const i2s_event_callbacks_t callbacks = {
666 i2s_channel_register_event_callback(this->
tx_handle_, &callbacks,
this);
688 xEventGroupSetBits(this->
event_group_, SpeakerEventGroupBits::STATE_STOPPED);
691 vTaskDelete(
nullptr);
694#ifndef USE_I2S_LEGACY
696 I2SAudioSpeaker *this_speaker = (I2SAudioSpeaker *) user_ctx;
697 bool overflow =
true;
698 xQueueOverwrite(this_speaker->i2s_event_queue_, &overflow);
virtual void mark_failed()
Mark this component as failed.
void status_clear_error()
bool status_has_error() const
void status_set_warning(const char *message="unspecified")
void status_set_error(const char *message="unspecified")
void status_clear_warning()
I2SAudioComponent * parent_
static std::unique_ptr< RingBuffer > create(size_t len)
uint32_t get_sample_rate() const
virtual bool set_mute_off()=0
virtual bool set_volume(float volume)=0
virtual bool set_mute_on()=0
i2s_std_slot_mask_t std_slot_mask_
i2s_slot_bit_width_t slot_bit_width_
i2s_bits_per_chan_t bits_per_channel_
i2s_channel_fmt_t channel_
i2s_slot_mode_t slot_mode_
i2s_mclk_multiple_t mclk_multiple_
i2s_bits_per_sample_t bits_per_sample_
i2s_dac_mode_t internal_dac_mode_
esp_err_t start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info)
Starts the ESP32 I2S driver.
TaskHandle_t speaker_task_handle_
int16_t q15_volume_factor_
void stop_(bool wait_on_empty)
Sends a stop command to the speaker task via event_group_.
bool send_esp_err_to_event_group_(esp_err_t err)
Sets the corresponding ERR_ESP event group bits.
static bool i2s_overflow_cb(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx)
std::shared_ptr< RingBuffer > audio_ring_buffer_
void set_mute_state(bool mute_state) override
Mutes or unmute the speaker.
esp_err_t allocate_buffers_(size_t data_buffer_size, size_t ring_buffer_size)
Allocates the data buffer and ring buffer.
bool has_buffered_data() const override
size_t play(const uint8_t *data, size_t length, TickType_t ticks_to_wait) override
Plays the provided audio data.
i2s_chan_handle_t tx_handle_
void set_volume(float volume) override
Sets the volume of the speaker.
i2s_comm_format_t i2s_comm_fmt_
static void speaker_task(void *params)
Function for the FreeRTOS task handling audio output.
QueueHandle_t i2s_event_queue_
void delete_task_(size_t buffer_size)
Deletes the speaker's task.
EventGroupHandle_t event_group_
audio_dac::AudioDac * audio_dac_
audio::AudioStreamInfo audio_stream_info_
Providing packet encoding functions for exchanging data with a remote host.
RAMAllocator< T > ExternalRAMAllocator
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
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).