3 #include "AudioConfig.h"
4 #if defined(ESP32) && defined(USE_I2S) && \
5 ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) || \
8 #include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
9 #include "driver/i2s.h"
10 #include "esp_system.h"
12 #ifndef I2S_MCLK_MULTIPLE_DEFAULT
13 # define I2S_MCLK_MULTIPLE_DEFAULT ((i2s_mclk_multiple_t)0)
16 #define IS_I2S_IMPLEMENTED
28 friend class AnalogAudio;
42 if (info.
equals(cfg))
return true;
46 return i2s_set_sample_rates((i2s_port_t)cfg.port_no, cfg.
sample_rate) == ESP_OK;
67 return begin(cfg, cfg.pin_data, I2S_PIN_NO_CHANGE);
72 cfg, I2S_PIN_NO_CHANGE,
73 cfg.pin_data != I2S_PIN_NO_CHANGE ? cfg.pin_data : cfg.pin_data_rx);
75 return begin(cfg, cfg.pin_data, cfg.pin_data_rx);
77 LOGE(
"Did not expect go get here");
81 int available() {
return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
89 i2s_driver_uninstall(i2s_num);
101 if (isNoChannelConversion(cfg)) {
102 if (i2s_write(i2s_num, src, size_bytes, &result, ticks_to_wait_write) !=
106 LOGD(
"i2s_write %d -> %d bytes", size_bytes, result);
114 size_t readBytes(
void *dest,
size_t size_bytes) {
116 if (isNoChannelConversion(cfg)) {
117 if (i2s_read(i2s_num, dest, size_bytes, &result, ticks_to_wait_read) !=
123 uint8_t temp[size_bytes * 2];
124 if (i2s_read(i2s_num, temp, size_bytes * 2, &result,
125 ticks_to_wait_read) != ESP_OK) {
131 ChannelReducerT<int16_t> reducer16(1, 2);
132 result = reducer16.convert((uint8_t *)dest, temp, result);
135 ChannelReducerT<int24_t> reducer24(1, 2);
136 result = reducer24.convert((uint8_t *)dest, temp, result);
139 ChannelReducerT<int32_t> reducer32(1, 2);
140 result = reducer32.convert((uint8_t *)dest, temp, result);
147 LOGE(
"Invalid channels: %d", cfg.
channels);
152 void setWaitTimeReadMs(TickType_t ms) {
153 ticks_to_wait_read = pdMS_TO_TICKS(ms);
155 void setWaitTimeWriteMs(TickType_t ms) {
156 ticks_to_wait_write = pdMS_TO_TICKS(ms);
162 i2s_config_t i2s_config;
163 bool is_started =
false;
164 TickType_t ticks_to_wait_read = portMAX_DELAY;
165 TickType_t ticks_to_wait_write = portMAX_DELAY;
167 bool isNoChannelConversion(I2SConfigESP32 cfg) {
168 if (cfg.channels == 2)
return true;
169 if (cfg.channels == 1 && cfg.channel_format == I2S_CHANNEL_FMT_ALL_RIGHT)
171 if (cfg.channels == 1 && cfg.channel_format == I2S_CHANNEL_FMT_ALL_LEFT)
173 if (cfg.channels == 1 && cfg.channel_format == I2S_CHANNEL_FMT_ONLY_RIGHT)
175 if (cfg.channels == 1 && cfg.channel_format == I2S_CHANNEL_FMT_ONLY_LEFT)
185 this->i2s_num = (i2s_port_t)cfg.port_no;
188 i2s_config_t i2s_config_new = {
190 .sample_rate = (eps32_i2s_sample_rate_type)cfg.
sample_rate,
192 .channel_format = (i2s_channel_fmt_t)cfg.channel_format,
193 .communication_format = toCommFormat(cfg.i2s_format),
194 .intr_alloc_flags = 0,
195 .dma_buf_count = cfg.buffer_count,
196 .dma_buf_len = cfg.buffer_size,
197 .use_apll = (bool)cfg.use_apll,
198 .tx_desc_auto_clear = cfg.auto_clear,
199 #
if ESP_IDF_VERSION_MAJOR >= 4
200 .fixed_mclk = (
int)(cfg.fixed_mclk > 0 ? cfg.fixed_mclk : 0),
201 .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
202 .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
205 i2s_config = i2s_config_new;
210 LOGD(
"%s",
"I2S restarting");
214 LOGD(
"i2s_driver_install");
215 if (i2s_driver_install(i2s_num, &i2s_config, 0, NULL) != ESP_OK) {
216 LOGE(
"%s - %s", __func__,
"i2s_driver_install");
220 if (this->cfg.signal_type == Digital || this->cfg.signal_type == PDM) {
221 i2s_pin_config_t pin_config = {
222 #if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 4, 0)
223 .mck_io_num = cfg.pin_mck,
225 .bck_io_num = cfg.pin_bck,
226 .ws_io_num = cfg.pin_ws,
227 .data_out_num = txPin,
228 .data_in_num = rxPin};
231 if (i2s_set_pin(i2s_num, &pin_config) != ESP_OK) {
232 LOGE(
"%s - %s", __func__,
"i2s_set_pin");
235 LOGD(
"Using built in DAC");
237 i2s_set_pin(i2s_num, NULL);
241 LOGD(
"i2s_zero_dma_buffer");
242 i2s_zero_dma_buffer(i2s_num);
245 LOGD(
"%s - %s", __func__,
"started");
250 void setChannels(
int channels) { cfg.channels = channels; }
254 const void *src,
size_t size_bytes) {
257 switch (bits_per_sample) {
259 for (j = 0; j < size_bytes; j++) {
261 int8_t *data = (int8_t *)src;
264 size_t result_call = 0;
265 if (i2s_write(i2s_num, frame,
sizeof(int8_t) * 2, &result_call,
266 ticks_to_wait_write) != ESP_OK) {
269 result += result_call;
275 for (j = 0; j < size_bytes / 2; j++) {
277 int16_t *data = (int16_t *)src;
280 size_t result_call = 0;
281 if (i2s_write(i2s_num, frame,
sizeof(int16_t) * 2, &result_call,
282 ticks_to_wait_write) != ESP_OK) {
285 result += result_call;
291 for (j = 0; j < size_bytes / 4; j++) {
296 size_t result_call = 0;
297 if (i2s_write(i2s_num, frame,
sizeof(
int24_t) * 2, &result_call,
298 ticks_to_wait_write) != ESP_OK) {
301 result += result_call;
307 for (j = 0; j < size_bytes / 4; j++) {
309 int32_t *data = (int32_t *)src;
312 size_t result_call = 0;
313 if (i2s_write(i2s_num, frame,
sizeof(int32_t) * 2, &result_call,
314 ticks_to_wait_write) != ESP_OK) {
317 result += result_call;
325 #pragma GCC diagnostic push
326 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
330 i2s_comm_format_t toCommFormat(
I2SFormat mode) {
332 case I2S_PHILIPS_FORMAT:
334 return (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_I2S;
335 case I2S_LEFT_JUSTIFIED_FORMAT:
337 return (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S |
338 I2S_COMM_FORMAT_I2S_MSB);
339 case I2S_RIGHT_JUSTIFIED_FORMAT:
341 return (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S |
342 I2S_COMM_FORMAT_I2S_LSB);
344 return (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_PCM_SHORT;
347 LOGE(
"unsupported mode");
348 return (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_I2S;
351 #pragma GCC diagnostic pop
353 int getModeDigital(I2SConfigESP32 &cfg) {
354 int i2s_format = cfg.is_master ? I2S_MODE_MASTER : I2S_MODE_SLAVE;
356 switch (cfg.rx_tx_mode) {
358 i2s_rx_tx = I2S_MODE_TX;
361 i2s_rx_tx = I2S_MODE_RX;
364 i2s_rx_tx = I2S_MODE_RX | I2S_MODE_TX;
367 LOGE(
"Undefined rx_tx_mode: %d", cfg.rx_tx_mode);
369 return (i2s_format | i2s_rx_tx);
373 i2s_mode_t toMode(I2SConfigESP32 &cfg) {
374 i2s_mode_t mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX);
375 switch (cfg.signal_type) {
377 mode = (i2s_mode_t)getModeDigital(cfg);
381 mode = (i2s_mode_t)(getModeDigital(cfg) | I2S_MODE_PDM);
385 #if defined(USE_ANALOG)
386 mode = (i2s_mode_t)(cfg.rx_tx_mode ? I2S_MODE_DAC_BUILT_IN
387 : I2S_MODE_ADC_BUILT_IN);
389 LOGE(
"mode not supported");
394 LOGW(
"signal_type undefined");
395 mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
402 using I2SDriver = I2SDriverESP32;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:28