I'm currently trying to read audio data from a PCM4222 ADC using I2S. I managed to get the ESP to read correct data from the ADC, however it seems like the ESP is skipping some samples, see image below.
This seems to always happen somewhere between sample number 400 and 500 and I cannot for the life of me figure out what the issue is.
Furthermore, is there a way to ensure seamless consecutive readouts? It seems like there also are a handful of samples missing between individual readouts.
Minimal working example:
Code: Select all
// Include I2S library
#include <driver/i2s.h>
// Define I2S settings
#define I2S_BCK_PIN 14
#define I2S_LRCK_PIN 25
#define I2S_DATA_PIN 26
#define SAMPLE_RATE 48000
#define DMA_BUF_LEN 1024
#define DMA_BUF_COUNT 2
void setup()
{
// Initialize serial communication
Serial.begin(115200);
// Configure I2S
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB),
.intr_alloc_flags = 0,
.dma_buf_count = DMA_BUF_COUNT,
.dma_buf_len = DMA_BUF_LEN
};
// Define I2S pins
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_BCK_PIN,
.ws_io_num = I2S_LRCK_PIN,
.data_out_num = -1,
.data_in_num = I2S_DATA_PIN
};
// Initialize I2S communication
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
}
void loop()
{
// Define variables
size_t bytesRead;
int32_t* i2sData = (int32_t*)malloc(2 * DMA_BUF_LEN * sizeof(int32_t));
// Read data for both left and right channels
i2s_read(I2S_NUM_0, i2sData, 2 * DMA_BUF_LEN * sizeof(int32_t), &bytesRead, portMAX_DELAY);
for (uint16_t i = 0; i < DMA_BUF_LEN; ++i)
{
// Discard first bit and last 7 bits
i2sData[2 * i] = (i2sData[2 * i] >> 7) & 0xFFFFFF;
i2sData[2 * i + 1] = (i2sData[2 * i + 1] >> 7) & 0xFFFFFF;
// Sign extend
i2sData[2 * i] <<= 8;
i2sData[2 * i] >>= 8;
i2sData[2 * i + 1] <<= 8;
i2sData[2 * i + 1] >>= 8;
// Print right channel data for debugging purposes
Serial.print(i); Serial.print("\t"); Serial.println(i2sData[2 * i + 1]);
}
Serial.print("");
// De-allocate memory used for data samples
free(i2sData);
}