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