5 #include <driver/i2s.h> 16 static const uint8_t DMA_BUFFER_DURATION_MS = 15;
17 static const size_t DMA_BUFFERS_COUNT = 4;
19 static const size_t TASK_DELAY_MS = DMA_BUFFER_DURATION_MS * DMA_BUFFERS_COUNT / 2;
21 static const size_t TASK_STACK_SIZE = 4096;
22 static const ssize_t TASK_PRIORITY = 23;
24 static const size_t I2S_EVENT_QUEUE_COUNT = DMA_BUFFERS_COUNT + 1;
26 static const char *
const TAG =
"i2s_audio.speaker";
49 static esp_err_t err_bit_to_esp_err(uint32_t bit) {
52 return ESP_ERR_INVALID_STATE;
54 return ESP_ERR_INVALID_ARG;
56 return ESP_ERR_INVALID_SIZE;
58 return ESP_ERR_NO_MEM;
60 return ESP_ERR_NOT_SUPPORTED;
75 static void q15_multiplication(
const int16_t *input, int16_t *output,
size_t len, int16_t c) {
76 for (
int i = 0; i <
len; i++) {
77 int32_t acc = (int32_t) input[i] * (int32_t) c;
78 output[i] = (int16_t) (acc >> 15);
86 static const std::vector<int16_t> Q15_VOLUME_SCALING_FACTORS = {
87 0, 116, 122, 130, 137, 146, 154, 163, 173, 183, 194, 206, 218, 231, 244,
88 259, 274, 291, 308, 326, 345, 366, 388, 411, 435, 461, 488, 517, 548, 580,
89 615, 651, 690, 731, 774, 820, 868, 920, 974, 1032, 1094, 1158, 1227, 1300, 1377,
90 1459, 1545, 1637, 1734, 1837, 1946, 2061, 2184, 2313, 2450, 2596, 2750, 2913, 3085, 3269,
91 3462, 3668, 3885, 4116, 4360, 4619, 4893, 5183, 5490, 5816, 6161, 6527, 6914, 7324, 7758,
92 8218, 8706, 9222, 9770, 10349, 10963, 11613, 12302, 13032, 13805, 14624, 15491, 16410, 17384, 18415,
93 19508, 20665, 21891, 23189, 24565, 26022, 27566, 29201, 30933, 32767};
96 ESP_LOGCONFIG(TAG,
"Setting up I2S Audio Speaker...");
101 ESP_LOGE(TAG,
"Failed to create event group");
108 uint32_t event_group_bits = xEventGroupGetBits(this->
event_group_);
111 ESP_LOGD(TAG,
"Starting Speaker");
113 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_STARTING);
116 ESP_LOGD(TAG,
"Started Speaker");
118 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_RUNNING);
123 ESP_LOGD(TAG,
"Stopping Speaker");
125 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::STATE_STOPPING);
129 ESP_LOGD(TAG,
"Stopped Speaker");
138 xEventGroupClearBits(this->
event_group_, SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START);
143 ESP_LOGW(TAG,
"Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
148 this->
status_set_error(
"Failed to adjust I2S bus to match the incoming audio");
150 "Incompatible audio format: sample rate = %" PRIu32
", channels = %" PRIu8
", bits per sample = %" PRIu8,
152 this->audio_stream_info_.bits_per_sample);
168 ssize_t decibel_index = remap<ssize_t, float>(volume, 0.0f, 1.0f, 0, Q15_VOLUME_SCALING_FACTORS.size() - 1);
197 ESP_LOGE(TAG,
"Cannot play audio, speaker failed to setup");
204 size_t bytes_written = 0;
211 bytes_written = temp_ring_buffer->write_without_replacement((
void *) data, length, ticks_to_wait);
214 return bytes_written;
226 uint32_t event_group_bits =
243 const uint32_t bytes_per_ms =
246 const size_t dma_buffers_size = DMA_BUFFERS_COUNT * DMA_BUFFER_DURATION_MS * bytes_per_ms;
249 const size_t ring_buffer_size =
261 bool stop_gracefully =
false;
262 uint32_t last_data_received_time =
millis();
263 bool tx_dma_underflow =
false;
267 event_group_bits = xEventGroupGetBits(this_speaker->
event_group_);
273 stop_gracefully =
true;
282 i2s_event_t i2s_event;
284 if (i2s_event.type == I2S_EVENT_TX_Q_OVF) {
285 tx_dma_underflow =
true;
289 size_t bytes_to_read = dma_buffers_size;
291 pdMS_TO_TICKS(TASK_DELAY_MS));
293 if (bytes_read > 0) {
294 size_t bytes_written = 0;
303 i2s_write(this_speaker->
parent_->get_port(), this_speaker->
data_buffer_, bytes_read, &bytes_written,
306 i2s_write_expand(this_speaker->
parent_->get_port(), this_speaker->
data_buffer_, bytes_read,
311 if (bytes_written != bytes_read) {
314 tx_dma_underflow =
false;
315 last_data_received_time =
millis();
318 if (stop_gracefully && tx_dma_underflow) {
326 i2s_driver_uninstall(this_speaker->
parent_->get_port());
328 this_speaker->
parent_->unlock();
374 case ESP_ERR_INVALID_STATE:
377 case ESP_ERR_INVALID_ARG:
380 case ESP_ERR_INVALID_SIZE:
386 case ESP_ERR_NOT_SUPPORTED:
403 return ESP_ERR_NO_MEM;
412 return ESP_ERR_NO_MEM;
421 return ESP_ERR_NOT_SUPPORTED;
424 if ((i2s_bits_per_sample_t) audio_stream_info.
bits_per_sample > this->bits_per_sample_) {
426 return ESP_ERR_NOT_SUPPORTED;
429 if (!this->
parent_->try_lock()) {
430 return ESP_ERR_INVALID_STATE;
433 i2s_channel_fmt_t channel = this->
channel_;
435 if (audio_stream_info.
channels == 1) {
436 if (this->
channel_ == I2S_CHANNEL_FMT_ONLY_LEFT) {
437 channel = I2S_CHANNEL_FMT_ONLY_LEFT;
439 channel = I2S_CHANNEL_FMT_ONLY_RIGHT;
441 }
else if (audio_stream_info.
channels == 2) {
442 channel = I2S_CHANNEL_FMT_RIGHT_LEFT;
445 int dma_buffer_length = DMA_BUFFER_DURATION_MS * this->
sample_rate_ / 1000;
447 i2s_driver_config_t config = {
448 .mode = (i2s_mode_t) (this->
i2s_mode_ | I2S_MODE_TX),
451 .channel_format = channel,
453 .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
454 .dma_buf_count = DMA_BUFFERS_COUNT,
455 .dma_buf_len = dma_buffer_length,
457 .tx_desc_auto_clear =
true,
458 .fixed_mclk = I2S_PIN_NO_CHANGE,
459 .mclk_multiple = I2S_MCLK_MULTIPLE_256,
461 #if SOC_I2S_SUPPORTS_TDM 462 .chan_mask = (i2s_channel_t) (I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1),
466 .bit_order_msb =
false,
470 #if SOC_I2S_SUPPORTS_DAC 472 config.mode = (i2s_mode_t) (config.mode | I2S_MODE_DAC_BUILT_IN);
484 #if SOC_I2S_SUPPORTS_DAC 487 i2s_pin_config_t pin_config = this->
parent_->get_pin_config();
488 pin_config.data_out_num = this->
dout_pin_;
490 err = i2s_set_pin(this->
parent_->get_port(), &pin_config);
491 #if SOC_I2S_SUPPORTS_DAC 499 i2s_driver_uninstall(this->
parent_->get_port());
518 vTaskDelete(
nullptr);
value_type const & value() const
size_t play(const uint8_t *data, size_t length, TickType_t ticks_to_wait) override
Plays the provided audio data.
EventGroupHandle_t event_group_
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.
esp_err_t allocate_buffers_(size_t data_buffer_size, size_t ring_buffer_size)
Allocates the data buffer and ring buffer.
virtual bool set_mute_off()=0
virtual bool set_mute_on()=0
static void speaker_task(void *params)
Function for the FreeRTOS task handling audio output.
void status_set_warning(const char *message="unspecified")
void set_volume(float volume) override
Sets the volume of the speaker.
i2s_dac_mode_t internal_dac_mode_
uint32_t IRAM_ATTR HOT millis()
bool status_has_error() const
void status_set_error(const char *message="unspecified")
i2s_channel_fmt_t channel_
esp_err_t start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info)
Starts the ESP32 I2S driver.
void status_clear_warning()
TaskHandle_t speaker_task_handle_
optional< uint32_t > timeout_
void set_mute_state(bool mute_state) override
Mutes or unmute the speaker.
void deallocate(T *p, size_t n)
virtual bool set_volume(float volume)=0
void status_clear_error()
i2s_bits_per_sample_t bits_per_sample_
virtual void mark_failed()
Mark this component as failed.
audio_dac::AudioDac * audio_dac_
void delete_task_(size_t buffer_size)
Deletes the speaker's task.
std::shared_ptr< RingBuffer > audio_ring_buffer_
size_t get_bytes_per_sample() const
Implementation of SPI Controller mode.
bool has_buffered_data() const override
i2s_bits_per_chan_t bits_per_channel_
QueueHandle_t i2s_event_queue_
An STL allocator that uses SPI or internal RAM.
static std::unique_ptr< RingBuffer > create(size_t len)
uint32_t buffer_duration_ms_
audio::AudioStreamInfo audio_stream_info_
i2s_comm_format_t i2s_comm_fmt_
int16_t q15_volume_factor_