ESP32 Converting a 16 bit audio file to 24 bit for I2S
Posted: Sun May 25, 2025 7:45 pm
I am trying to convert a 16 bit audio samples to 24 bit audio samples file for replaying and mixing purposes. I am shifting it to the left by 8 bytes and then send it to the i2s_channel but the sound im getting is very distorted. This should work, because im doing the sign assignment correct. I am able to get a nice sound when i transmit a 24 bit audio sample, so my configuration should not be the problem. Why is this not working ? I am using STD_PHILIPS_SLOT_DEFAULT_CONFIG and changing the data_bit_width to 24 bit accordingly. Also the master clock multiptle is already at I2S_MCLK_MULTIPLE_384
This is how i transmit a 24 bit audio sample that is originally 24 bit :
Code: Select all
i2s_channel_disable(*tx_chan);
i2s_std_slot_config_t std_slot_config_24 = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_24BIT, I2S_SLOT_MODE_STEREO);
std_slot_config_24.slot_bit_width = I2S_SLOT_BIT_WIDTH_32BIT;
i2s_channel_reconfig_std_slot(*tx_chan, &std_slot_config_24);
i2s_channel_enable(*tx_chan);
uint8_t* current_pos = (uint8_t*)buf + total_sent_bytes;
size_t num_samples = bytes_to_write / 2;
size_t bytes_to_write = num_samples * 3; // Convert to 24-bit
uint8_t *current_pos_16 = heap_caps_malloc(bytes_to_write, MALLOC_CAP_SPIRAM);
for (int i = 0; i < num_samples; i++) {
uint32_t sample = (uint32_t)((0x00) |
(current_pos[i*2] << 8) |
(current_pos[i*2 + 1] << 16));
current_pos_16[i*2] = sample & 0xFF; // Padding for 24-bit
current_pos_16[i*2 + 1] = (sample >> 8) & 0xFF;
current_pos_16[i*2 + 2] = (sample >> 16) & 0xFF;
}
ESP_ERROR_CHECK(i2s_channel_write(*tx_chan, current_pos_16, bytes_to_write, &written_bytes, 1000));
total_sent_bytes += written_bytes;
free(current_pos_16);Code: Select all
uint8_t* current_pos = (uint8_t*)buf + total_sent_bytes;
uint8_t *current_pos_24 = heap_caps_malloc(bytes_to_write, MALLOC_CAP_SPIRAM);
for (int i = 0; i < (bytes_to_write / 3); i++) {
uint32_t sample = (uint32_t)(current_pos[i*3] |
(current_pos[i*3 + 1] << 8) |
(current_pos[i*3 + 2] << 16));
current_pos_24[i*3] = sample & 0xFF;
current_pos_24[i*3 + 1] = (sample >> 8) & 0xFF;
current_pos_24[i*3 + 2] = (sample >> 16) & 0xFF;
}
ESP_ERROR_CHECK(i2s_channel_write(*tx_chan, current_pos_24, bytes_to_write, &written_bytes, 1000));
total_sent_bytes += written_bytes;
free(current_pos_24);