How to input audio using I2S PDM
Posted: Mon Apr 13, 2020 11:25 pm
Hi, I've spent all weekend trying to get my ESP32 to input audio using I2S.
Now i've had some success with I2S in 32 bit mode, however it was quite distorted, but you could make out that it was actually working a bit. I noticed it outputs a signed value, where the lowest byte is always 0x00.
I since realised i'm using a PDM mic (this one https://invensense.tdk.com/products/digital/inmp441/), which explains the distortion.
So i change my code to use PDM mode, at 16 bits (i believe PDM requires 16 bits on ESP32 because the driver is buggy or something?). But i get no output at all now.
Any suggestions?
The relevant parts of my code are below:
Now i've had some success with I2S in 32 bit mode, however it was quite distorted, but you could make out that it was actually working a bit. I noticed it outputs a signed value, where the lowest byte is always 0x00.
I since realised i'm using a PDM mic (this one https://invensense.tdk.com/products/digital/inmp441/), which explains the distortion.
So i change my code to use PDM mode, at 16 bits (i believe PDM requires 16 bits on ESP32 because the driver is buggy or something?). But i get no output at all now.
Any suggestions?
The relevant parts of my code are below:
Code: Select all
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = ESP_NOW_MAX_DATA_LEN * 2,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0,
};
if (ESP_OK != i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL)) {
Serial.println("i2s_driver_install: error");
}
i2s_pin_config_t pin_config = {
.bck_io_num = 14, // Bit Clock.
.ws_io_num = 15, // Word Select aka left/right clock aka LRCL.
.data_out_num = -1,
.data_in_num = 34, // Data-out of the mic.
};
if (ESP_OK != i2s_set_pin(I2S_NUM_0, &pin_config)) {
Serial.println("i2s_set_pin: error");
}
i2s_zero_dma_buffer(I2S_NUM_0);
...
esp_err_t err = i2s_read(I2S_NUM_0, &buffer16, sizeof(buffer16), &bytes_read, 1000);