I played a tone of 2000 Hz and dumped the data to serial, then ran an fft in matlab. The mirroring around fs/2 is expected but not four lines, and anything above 2500 Hz disappears.. My i2s setup:
Code: Select all
void init_i2s(size_t sample_rate) {
i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));
i2s_std_config_t rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg =
{
.mclk = I2S_GPIO_UNUSED,
.bclk = SCK_PIN,
.ws = WS_PIN,
.dout = I2S_GPIO_UNUSED,
.din = SD_PIN,
.invert_flags =
{
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &rx_std_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
}
Code: Select all
static int16_t* read_buffer;
static size_t read_bytes = 0;
void sampler_run_task(void* param) {
extern TaskHandle_t sample_buffer_task_handle;
read_buffer = (int16_t*)calloc(samp->overlap, sizeof(int16_t));
size_t buf_size = 1024;
while (true) {
ESP_ERROR_CHECK(i2s_channel_read(rx_chan, read_buffer, buf_size, &read_bytes, 1000));
if (read_bytes > 0) {
xTaskNotifyGive(sample_buffer_task_handle); // copy samples to buffer
}
}
free(read_buffer);
vTaskDelete(NULL);
}
void copy_sample_buffer_task(void* param) {
extern TaskHandle_t fft_task_handle;
while (true) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // wait to be notified
sampler_buffer_add(sample_buffer, read_buffer, read_bytes / sizeof(int16_t));
xTaskNotifyGive(fft_task_handle); // run fft
}
}
void sampler_buffer_add(int16* buffer, int16_t* batch, size_t length) {
// samples are in wrong order, swap every other
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2s.html#std-rx-mode
// for (size_t i = 0; i < length; i += 2) {
// buffer[i + 0] = bswap16(batch[i + 1]);
// buffer[i + 1] = bswap16(batch[i]);
// }
for (size_t i = 0; i < length; i += 1) {
// swap bytes to little endian
buffer[i] = bswap16(batch[i]);
}
}