arduino-audio-tools
Loading...
Searching...
No Matches
I2SDriverESP32V1.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
4#if defined(ESP32) && !USE_LEGACY_I2S || defined(DOXYGEN)
5
8#include "driver/i2s_pdm.h"
9#include "driver/i2s_std.h"
10#include "driver/i2s_tdm.h"
11#include "esp_system.h"
12
13#define IS_I2S_IMPLEMENTED
14
15namespace audio_tools {
16
17// i2s_port_t not valid any more in ESP-IDF v6, but we keep it for compatibility
18#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
19using i2s_port_t = int;
20#endif
21
22// support for Arduino ESP32 v3.0.7
23#if ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(5, 1, 4)
24#define I2S_MCLK_MULTIPLE_192 static_cast<i2s_mclk_multiple_t>(192)
25#endif
26
27
36 public:
39 I2SConfigESP32V1 c(mode);
40 return c;
41 }
44 // nothing to do
45 if (is_started) {
46 if (info.equals(cfg)) return true;
47 if (info.equalsExSampleRate(cfg)) {
49 LOGI("i2s_set_sample_rates: %d", (int)info.sample_rate);
51 }
52 } else {
53 LOGE("not started");
54 }
55 return false;
56 }
57
59 bool begin(RxTxMode mode) { return begin(defaultConfig(mode)); }
60
63 bool begin() { return (!is_started) ? begin(cfg) : true; }
64
67 TRACED();
68 this->cfg = cfg;
69
70 // stop if it is already open
71 if (is_started) end();
72
73 switch (cfg.rx_tx_mode) {
74 case TX_MODE:
75 return begin(cfg, cfg.pin_data, I2S_GPIO_UNUSED);
76 case RX_MODE:
77 // usually we expet cfg.pin_data but if the used assinged rx we might
78 // consider this one
79 return begin(cfg, I2S_GPIO_UNUSED,
80 cfg.pin_data_rx != I2S_GPIO_UNUSED ? cfg.pin_data_rx
81 : cfg.pin_data);
82 default:
84 }
85 LOGE("Did not expect go get here");
86 }
87
90
93
95 void end() {
96 TRACED();
97 if (rx_chan != nullptr) {
98 i2s_channel_disable(rx_chan);
99 i2s_del_channel(rx_chan);
100 rx_chan = nullptr;
101 }
102 if (tx_chan != nullptr) {
103 i2s_channel_disable(tx_chan);
104 i2s_del_channel(tx_chan);
105 tx_chan = nullptr;
106 }
107
108 is_started = false;
109 }
110
113
115 size_t writeBytes(const void *src, size_t size_bytes) {
116 TRACED();
117 size_t result;
118 assert(tx_chan != nullptr);
119 if (i2s_channel_write(tx_chan, src, size_bytes, &result,
120 ticks_to_wait_write) != ESP_OK) {
121 TRACEE();
122 }
123 return result;
124 }
125
126 size_t readBytes(void *dest, size_t size_bytes) {
127 size_t result = 0;
128 if (i2s_channel_read(rx_chan, dest, size_bytes, &result,
129 ticks_to_wait_read) != ESP_OK) {
130 TRACEE();
131 }
132 return result;
133 }
134
141
142 protected:
144 i2s_std_config_t i2s_config;
145 i2s_chan_handle_t tx_chan = nullptr; // I2S tx channel handler
146 i2s_chan_handle_t rx_chan = nullptr; // I2S rx channel handler
147 bool is_started = false;
150
153 i2s_chan_handle_t &tx_chan,
154 i2s_chan_handle_t &rx_chan, int txPin,
155 int rxPin) = 0;
156
157 virtual i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) = 0;
158 // changes the sample rate
160 i2s_chan_handle_t &tx_chan,
161 i2s_chan_handle_t &rx_chan) {
162 return false;
163 }
164
165 protected:
167 int get_bits_eff(int bits) { return (bits == 24) ? 32 : bits; }
168 };
169
170 struct DriverI2S : public DriverCommon {
171 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
172 i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
173 TRACED();
174 LOGI("tx: %d, rx: %d", txPin, rxPin);
175 i2s_std_config_t std_cfg;
176 std_cfg.clk_cfg = getClockConfig(cfg);
177 std_cfg.slot_cfg = getSlotConfig(cfg);
178 std_cfg.gpio_cfg = {
179 .mclk = (gpio_num_t)cfg.pin_mck,
180 .bclk = (gpio_num_t)cfg.pin_bck,
181 .ws = (gpio_num_t)cfg.pin_ws,
182 .dout = (gpio_num_t)txPin,
183 .din = (gpio_num_t)rxPin,
184 .invert_flags =
185 {
186 .mclk_inv = false,
187 .bclk_inv = false,
188 .ws_inv = false,
189 },
190 };
191
192
194 if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
195 LOGE("i2s_channel_init_std_mode %s", "tx");
196 return false;
197 }
198 if (i2s_channel_enable(tx_chan) != ESP_OK) {
199 LOGE("i2s_channel_enable %s", "tx");
200 return false;
201 }
202 }
203
205 if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
206 LOGE("i2s_channel_init_std_mode %s", "rx");
207 return false;
208 }
209 if (i2s_channel_enable(rx_chan) != ESP_OK) {
210 LOGE("i2s_channel_enable %s", "rx");
211 return false;
212 }
213 }
214
215 LOGD("%s - %s", __func__, "started");
216 return true;
217 }
218
219 protected:
220 i2s_std_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
221 TRACED();
222 i2s_std_slot_config_t result;
223 switch (cfg.i2s_format) {
225 case I2S_MSB_FORMAT:
226 result = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
227 (i2s_data_bit_width_t)cfg.bits_per_sample,
228 (i2s_slot_mode_t)cfg.channels);
229 break;
230 case I2S_PCM:
231 result = I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
232 (i2s_data_bit_width_t)cfg.bits_per_sample,
233 (i2s_slot_mode_t)cfg.channels);
234 break;
235 default:
236 result = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
237 (i2s_data_bit_width_t)cfg.bits_per_sample,
238 (i2s_slot_mode_t)cfg.channels);
239 }
240
241 // Update slot_mask if only one channel
242 if (cfg.channels == 1) {
243 switch (cfg.channel_format) {
245 result.slot_mask = I2S_STD_SLOT_LEFT;
246 break;
248 result.slot_mask = I2S_STD_SLOT_RIGHT;
249 break;
250 default:
251 LOGW("Using channel_format: I2SChannelSelect::Left for mono");
252 result.slot_mask = I2S_STD_SLOT_LEFT;
253 break;
254 }
255 }
256
257 return result;
258 }
259
261 TRACED();
262 i2s_chan_config_t result = I2S_CHANNEL_DEFAULT_CONFIG(
264 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
265 // use the legicy size parameters for frame num
266 int size = cfg.buffer_size * cfg.buffer_count;
267 int frame_size = get_bits_eff(cfg.bits_per_sample) * cfg.channels / 8;
268 frame_size = (frame_size == 0) ? 1 : frame_size;
269 if (size > 0) result.dma_frame_num = size / frame_size;
270 if (result.dma_frame_num == 0) result.dma_frame_num = 1;
271 LOGI("frame_size: %d", (int)frame_size);
272 LOGI("dma_frame_num: %d", (int)result.dma_frame_num);
273 LOGI("total buffer size: %d", (int)(result.dma_frame_num * frame_size));
274 result.auto_clear = cfg.auto_clear;
275 return result;
276 }
277
278 i2s_std_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
279 TRACED();
280 i2s_std_clk_config_t clk_cfg;// = I2S_STD_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
281 memset(&clk_cfg, 0, sizeof(i2s_std_clk_config_t));
282 clk_cfg.sample_rate_hz = cfg.sample_rate;
283 clk_cfg.clk_src = getClockSource(cfg);
284 // clk_cfg.ext_clk_freq_hz = 0;
285
286 if (cfg.mclk_multiple > 0) {
287 clk_cfg.mclk_multiple = (i2s_mclk_multiple_t)cfg.mclk_multiple;
288 LOGI("mclk_multiple=%d", clk_cfg.mclk_multiple);
289 } else {
290 if (cfg.bits_per_sample == 24) {
291 // mclk_multiple' should be the multiple of 3 while using 24-bit
292 // using the apll seems to double the frequency
293 clk_cfg.mclk_multiple = cfg.use_apll ? I2S_MCLK_MULTIPLE_192: I2S_MCLK_MULTIPLE_384;
294 LOGI("mclk_multiple=384");
295 } else {
296 // when use_appll is true, the multiple of 128 gives 256kHz
297 // using the apll seems to double the frequency
298 clk_cfg.mclk_multiple = cfg.use_apll ? I2S_MCLK_MULTIPLE_128 : I2S_MCLK_MULTIPLE_256;
299 LOGI("mclk_multiple=%d", clk_cfg.mclk_multiple);
300 }
301 }
302
303 return clk_cfg;
304 }
305
307 soc_periph_i2s_clk_src_t getClockSource(I2SConfigESP32V1 &cfg){
308 soc_periph_i2s_clk_src_t result = I2S_CLK_SRC_DEFAULT;
309 // use mclk pin as input in slave mode if supported
310 if (cfg.pin_mck != -1 && !cfg.is_master) {
311#if SOC_I2S_HW_VERSION_2
312 LOGI("pin_mclk is input");
313 result = I2S_CLK_SRC_EXTERNAL;
314 return result;
315#else
316 LOGE("pin_mclk as input not supported");
317#endif
318 }
319
320 // select APLL clock if possible
321 if (cfg.use_apll) {
322 // select clock source
323#if SOC_I2S_SUPPORTS_APLL
324 result = I2S_CLK_SRC_APLL;
325 LOGI("clk_src is I2S_CLK_SRC_APLL");
326#elif SOC_I2S_SUPPORTS_PLL_F160M
327 result = I2S_CLK_SRC_PLL_160M;
328 LOGI("clk_src is I2S_CLK_SRC_PLL_160M");
329#endif
330 }
331
332 return result;
333 }
334
335 bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
336 i2s_chan_handle_t &rx_chan) override {
337 bool rc = false;
338 auto clock_cfg = getClockConfig(cfg);
339 if (tx_chan != nullptr) {
340 i2s_channel_disable(tx_chan);
341 rc = i2s_channel_reconfig_std_clock(tx_chan, &clock_cfg) == ESP_OK;
342 i2s_channel_enable(tx_chan);
343 }
344 if (rx_chan != nullptr) {
345 i2s_channel_disable(rx_chan);
346 rc = i2s_channel_reconfig_std_clock(rx_chan, &clock_cfg) == ESP_OK;
347 i2s_channel_enable(rx_chan);
348 }
349 return rc;
350 }
351
353
354#ifdef USE_PDM
355
356 struct DriverPDM : public DriverCommon {
357 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
358 i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
359 if (cfg.rx_tx_mode == TX_MODE) {
360 return startTX(cfg, tx_chan, txPin);
361 } else if (cfg.rx_tx_mode == RX_MODE) {
362 return startRX(cfg, rx_chan, rxPin);
363 }
364 LOGE("Only RX and TX is supported for PDM")
365 return false;
366 }
367
368 protected:
369 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
370#ifdef SOC_I2S_HW_VERSION_2
371 return I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(
372 (i2s_data_bit_width_t)cfg.bits_per_sample,
373 (i2s_slot_mode_t)cfg.channels);
374#else
375 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
376 (i2s_data_bit_width_t)cfg.bits_per_sample,
377 (i2s_slot_mode_t)cfg.channels);
378#endif
379 }
380
381 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
382 return I2S_CHANNEL_DEFAULT_CONFIG(
383 (i2s_port_t)cfg.port_no,
384 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
385 }
386
387 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
388#if defined(I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG)
389 return I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
390#else
391 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
392#endif
393 }
394
395 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, int txPin) {
396 i2s_pdm_tx_config_t pdm_tx_cfg = {
397 .clk_cfg = getTxClockConfig(cfg),
398 .slot_cfg = getTxSlotConfig(cfg),
399 .gpio_cfg =
400 {
401 .clk = (gpio_num_t)cfg.pin_bck,
402 .dout = (gpio_num_t)txPin,
403#if SOC_I2S_PDM_MAX_TX_LINES > 1
404 .dout2 = I2S_GPIO_UNUSED, // required in IDF v6+
405#endif
406 .invert_flags =
407 {
408 .clk_inv = false,
409 },
410 },
411 };
412
413 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
414 LOGE("i2s_channel_init_pdm_tx_mode %s", "tx");
415 return false;
416 }
417 if (i2s_channel_enable(tx_chan) != ESP_OK) {
418 LOGE("i2s_channel_enable %s", "tx");
419 return false;
420 }
421 return true;
422 }
423
424#if defined(USE_PDM_RX)
425 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
426 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
427 (i2s_data_bit_width_t)cfg.bits_per_sample,
428 (i2s_slot_mode_t)cfg.channels);
429 }
430 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
431 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
432 }
433 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan, int rxPin) {
434 i2s_pdm_rx_config_t pdm_rx_cfg = {
435 .clk_cfg = getRxClockConfig(cfg),
436 .slot_cfg = getRxSlotConfig(cfg),
437 .gpio_cfg =
438 {
439 .clk = (gpio_num_t)cfg.pin_bck,
440 .din = (gpio_num_t)rxPin,
441 .invert_flags =
442 {
443 .clk_inv = false,
444 },
445 },
446 };
447
448 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
449 LOGE("i2s_channel_init_pdm_rx_mode %s", "rx");
450 return false;
451 }
452 if (i2s_channel_enable(rx_chan) != ESP_OK) {
453 LOGE("i2s_channel_enable %s", "tx");
454 return false;
455 }
456 return true;
457 }
458#else
459 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan, int rxPin) {
460 LOGE("PDM RX not supported");
461 return false;
462 }
463#endif
464 } pdm;
465
466#endif
467
468#ifdef USE_TDM
469 // example at
470 // https://github.com/espressif/esp-idf/blob/v5.3-dev/examples/peripherals/i2s/i2s_basic/i2s_tdm/main/i2s_tdm_example_main.c
471 struct DriverTDM : public DriverCommon {
472 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
473 i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
474 i2s_tdm_config_t tdm_cfg = {
475 .clk_cfg = getClockConfig(cfg),
476 .slot_cfg = getSlotConfig(cfg),
477 .gpio_cfg =
478 {
479 .mclk = (gpio_num_t)cfg.pin_mck,
480 .bclk = (gpio_num_t)cfg.pin_bck,
481 .ws = (gpio_num_t)cfg.pin_ws,
482 .dout = (gpio_num_t)txPin,
483 .din = (gpio_num_t)rxPin,
484 .invert_flags =
485 {
486 .mclk_inv = false,
487 .bclk_inv = false,
488 .ws_inv = false,
489 },
490 },
491 };
492
493 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
494 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
495 LOGE("i2s_channel_init_tdm_tx_mode %s", "tx");
496 return false;
497 }
498 }
499 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
500 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
501 LOGE("i2s_channel_init_tdm_tx_mode %s", "rx");
502 return false;
503 }
504 }
505 return true;
506 }
507
508 protected:
509 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
510 int slots = 0;
511 for (int j = 0; j < cfg.channels; j++) {
512 slots |= 1 << j;
513 }
514 // setup default format
515 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
516 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
517 (i2s_tdm_slot_mask_t)slots);
518
519 switch (cfg.i2s_format) {
521 case I2S_LSB_FORMAT:
523 case I2S_STD_FORMAT:
524 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
525 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
526 (i2s_tdm_slot_mask_t)slots);
527 break;
529 case I2S_MSB_FORMAT:
530 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
531 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
532 (i2s_tdm_slot_mask_t)slots);
533 break;
534 case I2S_PCM:
535 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
536 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
537 (i2s_tdm_slot_mask_t)slots);
538 break;
539 default:
540 LOGE("TDM: Unsupported format");
541 }
542
543 return slot_cfg;
544 }
545
546 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
547 return I2S_CHANNEL_DEFAULT_CONFIG(
548 (i2s_port_t)cfg.port_no,
549 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
550 }
551
552 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
553 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
554 }
555
556 } tdm;
557
558#endif
559
561
563 bool begin(I2SConfigESP32V1 cfg, int txPin, int rxPin) {
564 TRACED();
565 cfg.logInfo();
566 this->cfg = cfg;
567 if (cfg.channels <= 0 || cfg.channels > 2) {
568 LOGE("invalid channels: %d", cfg.channels);
569 return false;
570 }
571
572 DriverCommon &driver = getDriver(cfg);
573 if (!newChannels(cfg, driver)) {
574 end();
575 return false;
576 }
577
578 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
579 if (!is_started) {
580 end();
581 LOGE("Channels not started");
582 }
583 return is_started;
584 }
585
587 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
588 switch (cfg.rx_tx_mode) {
589 case RX_MODE:
590 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
591 LOGE("i2s_channel");
592 return false;
593 }
594 break;
595 case TX_MODE:
596 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
597 LOGE("i2s_channel");
598 return false;
599 }
600 break;
601 default:
602 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
603 LOGE("i2s_channel");
604 return false;
605 }
606 }
607 return true;
608 }
609
611 switch (cfg.signal_type) {
612 case Digital:
613 return i2s;
614#ifdef USE_PDM
615 case Analog:
616 case PDM:
617 return pdm;
618#endif
619#ifdef USE_TDM
620 case TDM:
621 return tdm;
622#endif
623 default:
624 break;
625 }
626 LOGE("Unsupported signal_type");
627 return i2s;
628 }
629};
630
631using I2SDriver = I2SDriverESP32V1;
632
633} // namespace audio_tools
634
635#endif
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define I2S_BUFFER_SIZE
Definition AudioToolsConfig.h:112
#define I2S_BUFFER_COUNT
Definition AudioToolsConfig.h:116
#define I2S_MCLK_MULTIPLE_192
Definition I2SDriverESP32V1.h:24
#define portMAX_DELAY
Definition QueueZephyr.h:14
#define pdMS_TO_TICKS(ms)
Definition QueueZephyr.h:17
uint32_t TickType_t
Definition QueueZephyr.h:11
#define assert(T)
Definition avr.h:10
Configuration for ESP32 i2s for IDF > 5.0.
Definition I2SConfigESP32V1.h:21
int buffer_count
total buffer is max buffer_count * buffer_size
Definition I2SConfigESP32V1.h:65
int pin_mck
Definition I2SConfigESP32V1.h:63
RxTxMode rx_tx_mode
public settings
Definition I2SConfigESP32V1.h:54
int pin_ws
Definition I2SConfigESP32V1.h:59
bool auto_clear
Definition I2SConfigESP32V1.h:69
I2SSignalType signal_type
Definition I2SConfigESP32V1.h:56
int pin_data
Definition I2SConfigESP32V1.h:61
int pin_data_rx
Definition I2SConfigESP32V1.h:62
bool use_apll
Definition I2SConfigESP32V1.h:68
int mclk_multiple
masterclock multiple (-1 = use default)
Definition I2SConfigESP32V1.h:73
bool is_master
Definition I2SConfigESP32V1.h:57
int pin_bck
Definition I2SConfigESP32V1.h:60
I2SFormat i2s_format
Definition I2SConfigESP32V1.h:55
void logInfo(const char *source="")
Definition I2SConfigESP32V1.h:75
int port_no
Definition I2SConfigESP32V1.h:58
I2SChannelSelect channel_format
Select left or right channel when channels == 1.
Definition I2SConfigESP32V1.h:71
int buffer_size
total buffer is max buffer_count * buffer_size
Definition I2SConfigESP32V1.h:67
Definition I2SDriverBase.h:7
Basic I2S API for the ESP32 (using the new API). https://docs.espressif.com/projects/esp-idf/en/v5....
Definition I2SDriverESP32V1.h:35
I2SConfigESP32V1 defaultConfig(RxTxMode mode)
Provides the default configuration.
Definition I2SDriverESP32V1.h:38
void setWaitTimeWriteMs(TickType_t ms)
Definition I2SDriverESP32V1.h:138
bool begin(I2SConfigESP32V1 cfg)
starts the DAC
Definition I2SDriverESP32V1.h:66
i2s_chan_handle_t rx_chan
Definition I2SDriverESP32V1.h:146
TickType_t ticks_to_wait_read
Definition I2SDriverESP32V1.h:148
audio_tools::I2SDriverESP32V1::DriverI2S i2s
void setWaitTimeReadMs(TickType_t ms)
Definition I2SDriverESP32V1.h:135
int available()
we assume the data is already available in the buffer
Definition I2SDriverESP32V1.h:89
bool is_started
Definition I2SDriverESP32V1.h:147
bool begin()
Definition I2SDriverESP32V1.h:63
bool setAudioInfo(AudioInfo info)
Potentially updates the sample rate (if supported)
Definition I2SDriverESP32V1.h:43
i2s_chan_handle_t tx_chan
Definition I2SDriverESP32V1.h:145
bool newChannels(I2SConfigESP32V1 &cfg, DriverCommon &driver)
Definition I2SDriverESP32V1.h:586
int availableForWrite()
We limit the write size to the buffer size.
Definition I2SDriverESP32V1.h:92
I2SConfigESP32V1 config()
provides the actual configuration
Definition I2SDriverESP32V1.h:112
DriverCommon & getDriver(I2SConfigESP32V1 &cfg)
Definition I2SDriverESP32V1.h:610
void end()
stops the I2C and unistalls the driver
Definition I2SDriverESP32V1.h:95
bool begin(RxTxMode mode)
starts the DAC with the default config
Definition I2SDriverESP32V1.h:59
bool begin(I2SConfigESP32V1 cfg, int txPin, int rxPin)
-> protected methods from I2SDriverESP32V1
Definition I2SDriverESP32V1.h:563
TickType_t ticks_to_wait_write
Definition I2SDriverESP32V1.h:149
size_t writeBytes(const void *src, size_t size_bytes)
writes the data to the I2S interface
Definition I2SDriverESP32V1.h:115
I2SConfigESP32V1 cfg
Definition I2SDriverESP32V1.h:143
i2s_std_config_t i2s_config
Definition I2SDriverESP32V1.h:144
size_t readBytes(void *dest, size_t size_bytes)
Definition I2SDriverESP32V1.h:126
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
@ Digital
Definition AudioTypes.h:438
@ PDM
Definition AudioTypes.h:440
@ TDM
Definition AudioTypes.h:441
@ Analog
Definition AudioTypes.h:439
@ I2S_STD_FORMAT
Definition AudioTypes.h:417
@ I2S_PHILIPS_FORMAT
Definition AudioTypes.h:420
@ I2S_LSB_FORMAT
Definition AudioTypes.h:418
@ I2S_LEFT_JUSTIFIED_FORMAT
Definition AudioTypes.h:422
@ I2S_RIGHT_JUSTIFIED_FORMAT
Definition AudioTypes.h:421
@ I2S_MSB_FORMAT
Definition AudioTypes.h:419
@ I2S_PCM
Definition AudioTypes.h:423
int i2s_port_t
Definition I2SDriverESP32V1.h:19
I2SDriverESP32 I2SDriver
Definition I2SDriverESP32.h:403
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
bool equals(AudioInfo alt)
Returns true if alt values are the same like the current values.
Definition AudioTypes.h:83
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
bool equalsExSampleRate(AudioInfo alt)
Checks if only the sample rate is different.
Definition AudioTypes.h:86
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
Definition I2SDriverESP32V1.h:151
virtual i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg)=0
int get_bits_eff(int bits)
24 bits are stored in a 32 bit integer
Definition I2SDriverESP32V1.h:167
virtual bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan, int txPin, int rxPin)=0
virtual bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan)
Definition I2SDriverESP32V1.h:159
Definition I2SDriverESP32V1.h:170
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan, int txPin, int rxPin)
Definition I2SDriverESP32V1.h:171
i2s_std_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg)
Definition I2SDriverESP32V1.h:220
i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg)
Definition I2SDriverESP32V1.h:260
i2s_std_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg)
Definition I2SDriverESP32V1.h:278
bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan) override
Definition I2SDriverESP32V1.h:335
soc_periph_i2s_clk_src_t getClockSource(I2SConfigESP32V1 &cfg)
select clock source dependent on is_master and use_apll
Definition I2SDriverESP32V1.h:307