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