Created
May 6, 2021 21:26
-
-
Save schreibfaul1/e6fe8774302c5873cce1305631c452b7 to your computer and use it in GitHub Desktop.
ESP32_ I2S_Microphone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// external HW | |
// 24-bit I2S Interface INMP441 Omnidirectional Microphone | |
// I2S PCM5102A DAC Decoder | |
#include "Arduino.h" | |
#include "driver/i2s.h" | |
#define TX_I2S_DOUT 25 // connect with external DAC | |
#define TX_I2S_BCLK 27 | |
#define TX_I2S_LRC 26 | |
#define RX_I2S_DIN 33 // connect with I2S microphone | |
#define RX_I2S_BCLK 12 | |
#define RX_I2S_LRC 14 | |
const i2s_port_t I2S_PORT_RX = I2S_NUM_1; | |
const i2s_port_t I2S_PORT_TX = I2S_NUM_0; | |
const uint32_t sample_rate = 44100; | |
const uint16_t buf_len = 512; | |
char buf[buf_len]; | |
size_t bytes_written = 0; | |
void init_i2s() { | |
/* TX: I2S_NUM_0 */ | |
i2s_config_t i2s_config_tx = { | |
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX), | |
.sample_rate = sample_rate, | |
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, | |
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // 2-channels | |
.communication_format = (i2s_comm_format_t) I2S_COMM_FORMAT_I2S_MSB, | |
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1 | |
.dma_buf_count = 16, // number of buffers, 128 max. | |
.dma_buf_len = 256, // size of each buffer | |
.use_apll = false, | |
.tx_desc_auto_clear = true, // new in V1.0.1 | |
.fixed_mclk = I2S_PIN_NO_CHANGE, | |
}; | |
i2s_pin_config_t pin_config_tx = { | |
.bck_io_num = TX_I2S_BCLK, | |
.ws_io_num = TX_I2S_LRC, | |
.data_out_num = TX_I2S_DOUT, | |
.data_in_num = I2S_PIN_NO_CHANGE | |
}; | |
i2s_driver_install(I2S_PORT_TX, &i2s_config_tx, 0, NULL); | |
i2s_set_pin(I2S_PORT_TX, &pin_config_tx); | |
/* RX: I2S_NUM_1 */ | |
i2s_config_t i2s_config_rx = { | |
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX), // Only TX | |
.sample_rate = sample_rate, | |
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // Only 8-bit DAC support | |
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // 2-channels | |
.communication_format = (i2s_comm_format_t) I2S_COMM_FORMAT_I2S_MSB, | |
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1 | |
.dma_buf_count = 16, // number of buffers, 128 max. | |
.dma_buf_len = 256, // size of each buffer | |
.use_apll = false, | |
.tx_desc_auto_clear = true, // new in V1.0.1 | |
.fixed_mclk = I2S_PIN_NO_CHANGE, | |
}; | |
i2s_pin_config_t pin_config_rx = { | |
.bck_io_num = RX_I2S_BCLK, | |
.ws_io_num = RX_I2S_LRC, | |
.data_out_num = I2S_PIN_NO_CHANGE, | |
.data_in_num = RX_I2S_DIN | |
}; | |
i2s_driver_install(I2S_PORT_RX, &i2s_config_rx, 0, NULL); | |
i2s_set_pin(I2S_PORT_RX, &pin_config_rx); | |
} | |
void setup(){ | |
init_i2s(); | |
} | |
void loop(){ | |
// char *buf_ptr_read = buf + 4; // connect L/R with ground | |
char *buf_ptr_read = buf; // connect L/R with VDD | |
char *buf_ptr_write = buf; | |
// read whole block of samples | |
size_t bytes_read = 0; | |
while(bytes_read == 0) { | |
i2s_read(I2S_PORT_RX, buf, buf_len, &bytes_read, portMAX_DELAY); | |
} | |
uint32_t samples_read = bytes_read / 2 / (I2S_BITS_PER_SAMPLE_32BIT / 8); | |
// convert 2x 32 bit stereo -> 1 x 16 bit mono | |
for(int i = 0; i < samples_read; i++) { | |
// left channel | |
int32_t sample = (buf_ptr_read[3] << 24) + (buf_ptr_read[2] << 16) + (buf_ptr_read[1] << 8) + buf_ptr_read[4]; | |
sample = sample >> 14; // gain | |
buf_ptr_write[0] = sample & 0x00FF; | |
buf_ptr_write[1] = (sample >>8) & 0x00FF; | |
// right channel | |
buf_ptr_write[2] = buf_ptr_write[0]; // mid | |
buf_ptr_write[3] = buf_ptr_write[1]; // high | |
buf_ptr_write += 2 * (I2S_BITS_PER_SAMPLE_16BIT / 8); | |
buf_ptr_read += 2 * (I2S_BITS_PER_SAMPLE_32BIT / 8); | |
} | |
// local echo | |
size_t bytes_written2; | |
bytes_written = samples_read * 2 * (I2S_BITS_PER_SAMPLE_16BIT / 8); | |
i2s_write(I2S_PORT_TX, buf, bytes_written, &bytes_written2, portMAX_DELAY); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment