Page 1 of 1

How to input audio using I2S PDM

Posted: Mon Apr 13, 2020 11:25 pm
by chris_oz
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:

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);

Re: How to input audio using I2S PDM

Posted: Tue Apr 14, 2020 2:03 am
by ESP_houwenxiang
Hi, @chris_oz

I saw the datasheet, The documentation says that this MIC uses a industry-standard 24-bit I²S interface. When using the I2S interface, what are your configuration parameters?

Re: How to input audio using I2S PDM

Posted: Tue Apr 14, 2020 4:00 am
by chris_oz
Hi, thanks for replying, really appreciate it :D

I also had a look through the datasheet and I came away confused.

It doesn't explicitly say it's a PDM mic or not, so I assumed that it was one, given the price.

Perhaps it doesn't require PDM mode. In fact, i can get audio (of very poor quality) when sampling in non-PDM mode, however the quality is so poor that i assumed the problem was that it requires PDM. I'll admit there's a chance that PDM is a red herring, that my distortion problem lies elsewhere.

My configuration parameters are as follows: (is this what you mean?)

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,
};
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.
};
Thanks again

Re: How to input audio using I2S PDM

Posted: Tue Apr 14, 2020 4:08 am
by ESP_houwenxiang
I mean the non-PDM mode configuration

Re: How to input audio using I2S PDM

Posted: Tue Apr 14, 2020 4:36 am
by chris_oz
So your question about PDM prompted me to search around, and the guy who created this INMP441 breakout PCB tells me that they *dont* use PDM to the best of his knowledge: https://hackaday.io/project/4411-inmp44 ... microphone

So perhaps this thread has run its course, and I apologise for potentially wasting your time :oops:

As for the non-PDM configuration:

Code: Select all

i2s_config_t i2s_config = {
	.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
	.sample_rate = 44100,
	.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
	.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 * 4,
	.use_apll = false,
	.tx_desc_auto_clear = false,
	.fixed_mclk = 0,
};
i2s_pin_config_t pin_config = {
	.bck_io_num = 14,   // Bit Clock.
	.ws_io_num = 15,    // Word Select aka left/right clock aka LRCL. 19?
	.data_out_num = -1,
	.data_in_num = 34,  // Data-out of the mic. (someone used 23 on forums). 34?
};

Re: How to input audio using I2S PDM

Posted: Thu Feb 11, 2021 7:19 pm
by wouterpeetermans
I've ran into the same problem but my mic was an actual pdm. Datasheet of esp32 says that when in pdm mode the ws pin becomes the clock signal. This should fix the problem and make sure that you get an output signal.