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...");
27 if (!this->
parent_->try_lock()) {
40 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
42 i2s_driver_config_t config = {
43 .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
45 .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
46 .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
47 .communication_format = I2S_COMM_FORMAT_STAND_I2S,
48 .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
52 .tx_desc_auto_clear =
true,
53 .fixed_mclk = I2S_PIN_NO_CHANGE,
54 .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
55 .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
57 #if SOC_I2S_SUPPORTS_DAC 59 config.mode = (i2s_mode_t) (config.mode | I2S_MODE_DAC_BUILT_IN);
63 esp_err_t err = i2s_driver_install(this_speaker->
parent_->get_port(), &config, 0,
nullptr);
75 #if SOC_I2S_SUPPORTS_DAC 78 i2s_pin_config_t pin_config = this_speaker->
parent_->get_pin_config();
79 pin_config.data_out_num = this_speaker->
dout_pin_;
81 i2s_set_pin(this_speaker->
parent_->get_port(), &pin_config);
82 #if SOC_I2S_SUPPORTS_DAC 91 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
93 int16_t buffer[BUFFER_SIZE / 2];
96 if (xQueueReceive(this_speaker->
buffer_queue_, &data_event, 100 / portTICK_PERIOD_MS) != pdTRUE) {
99 if (data_event.
stop) {
104 size_t bytes_written;
106 memmove(buffer, data_event.
data, data_event.
len);
107 size_t remaining = data_event.
len / 2;
110 while (remaining > 0) {
111 uint32_t sample = (buffer[current] << 16) | (buffer[current] & 0xFFFF);
113 esp_err_t err = i2s_write(this_speaker->
parent_->get_port(), &sample,
sizeof(sample), &bytes_written,
114 (10 / portTICK_PERIOD_MS));
117 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
125 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
128 i2s_zero_dma_buffer(this_speaker->
parent_->get_port());
131 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
133 i2s_driver_uninstall(this_speaker->
parent_->get_port());
136 xQueueSend(this_speaker->
event_queue_, &event, portMAX_DELAY);
153 xQueueSendToFront(this->
buffer_queue_, &data, portMAX_DELAY);
158 if (xQueueReceive(this->
event_queue_, &event, 0) == pdTRUE) {
159 switch (event.
type) {
161 ESP_LOGD(TAG,
"Starting I2S Audio Speaker");
164 ESP_LOGD(TAG,
"Started I2S Audio Speaker");
167 ESP_LOGD(TAG,
"Stopping I2S Audio Speaker");
178 ESP_LOGD(TAG,
"Stopped I2S Audio Speaker");
181 ESP_LOGW(TAG,
"Error writing to I2S: %s", esp_err_to_name(event.
err));
206 size_t remaining =
length;
208 while (remaining > 0) {
211 size_t to_send_length = std::min(remaining, BUFFER_SIZE);
212 event.len = to_send_length;
213 memcpy(event.
data, data + index, to_send_length);
217 remaining -= to_send_length;
218 index += to_send_length;
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_
void status_clear_warning()
QueueHandle_t event_queue_
size_t play(const uint8_t *data, size_t length) override
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
bool has_buffered_data() const override
uint8_t data[BUFFER_SIZE]
void IRAM_ATTR HOT delay(uint32_t ms)