New I2S driver microphone bytes format
Posted: Sun Feb 09, 2025 1:10 am
Hi,
I want to move from a setup using Arduino IDE with legacy I2S ("driver/i2s.h") to ESP-IDF and "driver/i2s_std.h".
The hardware / logic setup is:
Audio data is:
Works fine. After decoding to int16 the audio can look as this example:
I want to replicate this setup with ESP-IDF and new I2S driver as:
How can I get the correct signed int16 values of audio data with the new I2S driver?
Could this be a bug? I strived to set the same settings using both drivers (old and new), so I'd expect them to give the same results.
I want to move from a setup using Arduino IDE with legacy I2S ("driver/i2s.h") to ESP-IDF and "driver/i2s_std.h".
The hardware / logic setup is:
- ESP32-C3
- MEMS microphone INMP411
- GPIO numbers used: WS 0, SCK 1, SD 2
- 16-bit, mono, 44.1kHz
- data is send over network socket to a host
Code: Select all
const 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_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
.intr_alloc_flags = 0,
.dma_desc_num = 10,
.dma_frame_num = 1024,
.use_apll = false
};
Code: Select all
int16_t volume_samples[1024];
size_t bytesIn = 0;
i2s_read(I2S_ESP32_PORT, &volume_samples, 2048, &bytesIn, portMAX_DELAY);
- send as:
Code: Select all
send(sockfd, volume_samples, bytesIn, 0);
- received (for testing) in a Python script and stored as:
Code: Select all
with open(filename, "ab") as file:
data = current_client_socket.recv(2048)
if data:
file.write(data)
- decoded to signed int16 in a Python script as:
Code: Select all
file = open(args.filename, "r")
volumes = np.fromfile(file, dtype=np.int16)
- config
Code: Select all
i2s_chan_config_t rx_chan_cfg = {
.id = I2S_NUM_AUTO,
.role = I2S_ROLE_MASTER,
.dma_desc_num = 10,
.dma_frame_num = 1024,
};
i2s_std_config_t rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg =
{
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_1,
.ws = GPIO_NUM_0,
.dout = I2S_GPIO_UNUSED,
.din = GPIO_NUM_2,
.invert_flags =
{
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT;
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &rx_std_cfg));
- reading data
Code: Select all
i2s_channel_read(rx_chan, &volume_samples, 2048, &bytesIn, portMAX_DELAY)
- data is sent, received and decoded in the same way as outlined above
How can I get the correct signed int16 values of audio data with the new I2S driver?
Could this be a bug? I strived to set the same settings using both drivers (old and new), so I'd expect them to give the same results.