I am in the process of integrating the ESP32 with a MAX98091 codec for two way communication over I2S. So far I have been having problems with reading data over DMA and playing it back.
I am using an devkit for the codec which allows me to take an I2S audio input from my computer and have the codec play it through some headphones. In order to debug reading and writing from the I2S DMA, I disconnected the jumpers that connect the input I2S from the computer to the codec, and put my ESP32 "in the middle". So now I am getting an I2S signal from my computer going into the ESP, and then back out via another I2S channel to the codec.
So far I am able to read about a second (I think?) of audio and play it back right after, but with a large amount of distortion (talking is not describable and music is barely recognizable).
I am wondering if anyone has some tips for what I should try doing to get this to work. I've done some basic stuff like playing with the sample rates, sizes, and DMA buffer sizes without much success.
Here is the code:
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"
#define SAMPLE_RATE (16000)
#define SAMPLE_SIZE (16)
uint8_t *buf;
static void test(void)
{
i2s_start(0);
size_t bytes_read = 0;
i2s_read(0, buf, SAMPLE_RATE*SAMPLE_SIZE/4,&bytes_read, 1000);
printf("Read: %d bytes\n", bytes_read);
i2s_stop(0);
i2s_start(1);
size_t bytes_written = 0;
i2s_write(1, buf, SAMPLE_RATE*SAMPLE_SIZE/4,&bytes_written, 1000);
printf("Wrote %d bytes\n",bytes_written);
i2s_stop(1);
//i2s_zero_dma_buffer(0);
//i2s_zero_dma_buffer(1);
}
void app_main()
{
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX,
.sample_rate = SAMPLE_RATE,
.bits_per_sample = SAMPLE_SIZE,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
.dma_buf_count = 32,
.dma_buf_len = 64,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
};
i2s_pin_config_t pin_config = {
.bck_io_num = 26,
.ws_io_num = 25,
.data_out_num = -1,
.data_in_num = 12
};
i2s_config_t i2s_config_2 = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX,
.sample_rate = SAMPLE_RATE,
.bits_per_sample = SAMPLE_SIZE,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
.dma_buf_count = 32,
.dma_buf_len = 64,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
};
i2s_pin_config_t pin_config_2 = {
.bck_io_num = 27,
.ws_io_num = 33,
.data_out_num = 32,
.data_in_num = -1
};
i2s_driver_install(0, &i2s_config, 0, NULL);
i2s_set_pin(0, &pin_config);
i2s_driver_install(1, &i2s_config_2, 0, NULL);
i2s_set_pin(1, &pin_config_2);
buf = calloc(SAMPLE_RATE*8,sizeof(char));
while (1) {
test();
}
}
https://www.maximintegrated.com/en/prod ... 3TQFN.html
Thanks!
- Rob