3 #include "AudioConfig.h"
4 #if defined(ESP32) && defined(USE_I2S) && \
5 ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) || \
8 #include "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"
34 if (info.
equals(cfg))
return true;
37 LOGI(
"i2s_set_sample_rates: %d", (
int) info.
sample_rate);
38 return getDriver(cfg).changeSampleRate(cfg, rx_chan, tx_chan);
51 bool begin() {
return (!is_started) ?
begin(cfg) :
true; }
59 if (is_started)
end();
63 return begin(cfg, cfg.pin_data, I2S_GPIO_UNUSED);
67 return begin(cfg, I2S_GPIO_UNUSED,
68 cfg.pin_data_rx != I2S_GPIO_UNUSED ? cfg.pin_data_rx
71 return begin(cfg, cfg.pin_data, cfg.pin_data_rx);
73 LOGE(
"Did not expect go get here");
77 int available() {
return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
85 if (rx_chan !=
nullptr) {
86 i2s_channel_disable(rx_chan);
87 i2s_del_channel(rx_chan);
90 if (tx_chan !=
nullptr) {
91 i2s_channel_disable(tx_chan);
92 i2s_del_channel(tx_chan);
106 if (i2s_channel_write(tx_chan, src, size_bytes, &result,
107 ticks_to_wait_write) != ESP_OK) {
113 size_t readBytes(
void *dest,
size_t size_bytes) {
115 if (i2s_channel_read(rx_chan, dest, size_bytes, &result,
116 ticks_to_wait_read) != ESP_OK) {
122 void setWaitTimeReadMs(TickType_t ms) {
123 ticks_to_wait_read = pdMS_TO_TICKS(ms);
125 void setWaitTimeWriteMs(TickType_t ms) {
126 ticks_to_wait_write = pdMS_TO_TICKS(ms);
131 i2s_std_config_t i2s_config;
132 i2s_chan_handle_t tx_chan =
nullptr;
133 i2s_chan_handle_t rx_chan =
nullptr;
134 bool is_started =
false;
135 TickType_t ticks_to_wait_read = portMAX_DELAY;
136 TickType_t ticks_to_wait_write = portMAX_DELAY;
141 i2s_chan_handle_t &tx_chan,
142 i2s_chan_handle_t &rx_chan,
int txPin,
146 i2s_chan_handle_t &tx_chan,
147 i2s_chan_handle_t &rx_chan) {
155 switch (cfg.i2s_format) {
156 case I2S_RIGHT_JUSTIFIED_FORMAT:
158 case I2S_PHILIPS_FORMAT:
160 return I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
163 case I2S_LEFT_JUSTIFIED_FORMAT:
165 return I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
169 return I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
175 return I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
182 return I2S_CHANNEL_DEFAULT_CONFIG(
183 (i2s_port_t)cfg.port_no,
184 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
189 i2s_std_clk_config_t clk_cfg =
190 I2S_STD_CLK_DEFAULT_CONFIG((uint32_t)cfg.
sample_rate);
193 clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384;
199 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
201 LOGI(
"tx: %d, rx: %d", txPin, rxPin);
202 i2s_std_config_t std_cfg = {
203 .clk_cfg = getClockConfig(cfg),
204 .slot_cfg = getSlotConfig(cfg),
207 .mclk = (gpio_num_t)cfg.pin_mck,
208 .bclk = (gpio_num_t)cfg.pin_bck,
209 .ws = (gpio_num_t)cfg.pin_ws,
210 .dout = (gpio_num_t)txPin,
211 .din = (gpio_num_t)rxPin,
222 if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
223 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
226 if (i2s_channel_enable(tx_chan) != ESP_OK) {
227 LOGE(
"i2s_channel_enable %s",
"tx");
233 if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
234 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
237 if (i2s_channel_enable(rx_chan) != ESP_OK) {
238 LOGE(
"i2s_channel_enable %s",
"rx");
243 LOGD(
"%s - %s", __func__,
"started");
248 i2s_chan_handle_t &rx_chan)
override {
250 auto clock_cfg = getClockConfig(cfg);
251 if (tx_chan !=
nullptr) {
252 i2s_channel_disable(tx_chan);
253 rc = i2s_channel_reconfig_std_clock(tx_chan, &clock_cfg) == ESP_OK;
254 i2s_channel_enable(tx_chan);
256 if (rx_chan !=
nullptr) {
257 i2s_channel_disable(rx_chan);
258 rc = i2s_channel_reconfig_std_clock(rx_chan, &clock_cfg) == ESP_OK;
259 i2s_channel_enable(rx_chan);
270 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
276 return I2S_CHANNEL_DEFAULT_CONFIG(
277 (i2s_port_t)cfg.port_no,
278 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
281 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
282 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
285 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
286 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
287 if (cfg.rx_tx_mode == TX_MODE) {
288 i2s_pdm_tx_config_t pdm_tx_cfg = {
289 .clk_cfg = getTxClockConfig(cfg),
290 .slot_cfg = getTxSlotConfig(cfg),
293 .clk = (gpio_num_t)cfg.pin_bck,
294 .dout = (gpio_num_t)txPin,
302 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
303 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
306 if (i2s_channel_enable(tx_chan) != ESP_OK) {
307 LOGE(
"i2s_channel_enable %s",
"tx");
311 LOGE(
"Only TX supported for PDM");
323 struct DriverTDM :
public DriverCommon {
324 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
326 for (
int j = 0; j < cfg.channels; j++) {
329 return I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
330 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
331 (i2s_tdm_slot_mask_t)slots);
334 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
335 return I2S_CHANNEL_DEFAULT_CONFIG(
336 (i2s_port_t)cfg.port_no,
337 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
340 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
341 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
344 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
345 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
346 i2s_tdm_config_t tdm_cfg = {
347 .clk_cfg = getClockConfig(cfg),
348 .slot_cfg = getSlotConfig(cfg),
351 .mclk = (gpio_num_t)cfg.pin_mck,
352 .bclk = (gpio_num_t)cfg.pin_bck,
353 .ws = (gpio_num_t)cfg.pin_ws,
354 .dout = (gpio_num_t)txPin,
355 .din = (gpio_num_t)rxPin,
365 if (cfg.rx_tx_mode == TX_MODE) {
366 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
367 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
371 if (cfg.rx_tx_mode == RX_MODE) {
372 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
373 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
392 LOGE(
"invalid channels: %d", cfg.
channels);
397 if (!newChannels(cfg, driver)) {
402 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
405 LOGE(
"Channels not started");
411 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
414 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
420 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
426 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
434 DriverCommon &getDriver(I2SConfigESP32V1 &cfg) {
435 switch (cfg.signal_type) {
450 LOGE(
"Unsupported singal_type");
455 using I2SDriver = I2SDriverESP32V1;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:26