I want to hook up an INVENSENSE ICS-43432 i2s mems mic to the first i2s port and an Adafruit Class D i2s to the second port.
They need not to be in sync.
Both i2s ports work, when I use them separately. But if I want to use them simultaneously, I get stuttering and crackling sound out of the speaker.
This happens when I set the i2s pin for the input port, even without any read operation on it.
If I memset the output samples to zero, there is silence.
I am using an Olimex ESP-POE-ISO board.
Does anyone know what the problem might be?
the code:
Code: Select all
#include <driver/i2s.h>
#define BUF_SIZE 512
#define SAMPLERATE 48000
const i2s_port_t I2S_PORT_IN = I2S_NUM_0;
const i2s_port_t I2S_PORT_OUT = I2S_NUM_1;
int32_t samples_stereo[BUF_SIZE*2];
// sine wave 1.5kHz @ 48000Hz
int lenSine = 32;
float sine[32] = {
0.0,
-0.195090322016118,
-0.382683432365079,
-0.555570233019592,
-0.707106781186539,
-0.831469612302538,
-0.923879532511281,
-0.980785280403227,
-1.0,
-0.980785280403233,
-0.923879532511293,
-0.831469612302555,
-0,70710678118656,
-0.555570233019617,
-0.382683432365107,
-0.195090322016147,
0.0,
0.195090322016108,
0.382683432365071,
0.555570233019585,
0.707106781186532,
0.831469612302532,
0.923879532511278,
0.980785280403226,
1.0,
0.980785280403235,
0.923879532511297,
0.83146961230256,
0.707106781186567,
0.555570233019626,
0.382683432365117,
// 0.195090322016158,
};
void setup()
{
Serial.begin(115200);
Serial.println("Configuring I2S...");
esp_err_t err;
const i2s_config_t i2s_config_in = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = SAMPLERATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = BUF_SIZE
};
const i2s_config_t i2s_config_out = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = SAMPLERATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
//.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = BUF_SIZE
};
i2s_pin_config_t pin_config_in = {
.bck_io_num = 4, // IIS_SCLK
.ws_io_num = 3, // IIS_LCLK
.data_out_num = -1,// IIS_DSIN
.data_in_num = 5 // IIS_DOUT
};
i2s_pin_config_t pin_config_out = {
.bck_io_num = 14, // IIS_SCLK
.ws_io_num = 13, // IIS_LCLK
.data_out_num = 15,// IIS_DSIN
.data_in_num = -1 // IIS_DOUT
};
err = i2s_driver_install(I2S_PORT_IN, &i2s_config_in, 0, NULL);
if (err != ESP_OK) {
Serial.printf("Failed installing INPUT driver: %d\n", err);
while (true);
}
err = i2s_driver_install(I2S_PORT_OUT, &i2s_config_out, 0, NULL);
if (err != ESP_OK) {
Serial.printf("Failed installing OUTPUT driver: %d\n", err);
while (true);
}
err = i2s_set_pin(I2S_PORT_IN, &pin_config_in);
if (err != ESP_OK) {
Serial.printf("Failed setting DIN pin: %d\n", err);
while (true);
}
err = i2s_set_pin(I2S_PORT_OUT, &pin_config_out);
if (err != ESP_OK) {
Serial.printf("Failed setting DOUT pin: %d\n", err);
while (true);
}
Serial.println("I2S driver installed and running.");
memset(samples_stereo, 0, BUF_SIZE*2);
}
void loop() {
int bytesRead;
// i2s_read(I2S_PORT_IN, (char *)samples, BUF_SIZE*4, (size_t*)&bytesRead, portMAX_DELAY);
for( int i=0; i< BUF_SIZE; i+=lenSine){
memcpy(&samples_stereo[i], (int32_t*)sine, lenSine);
memcpy(&samples_stereo[BUF_SIZE+i], (int32_t*)sine, lenSine);
}
//memset(&samples_stereo[0], 0, BUF_SIZE*2);
int bytesWritten;
i2s_write(I2S_PORT_OUT, (char *)samples_stereo, BUF_SIZE*8, (size_t*)&bytesWritten, portMAX_DELAY);
}