This has been driving me absolutely nuts for the past couple days and I have been able to resolve the issue. Some help is greatly appreciated!
I'm trying to use my INMP441 as an input for my ESP-ADF pipeline but it's not working, however using the same i2s config for the more traditional init of the microphone works fine.
'Traditional' code which is working:
Code: Select all
void i2s_init_old(){
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan);
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = BCLK_PIN,
.ws = LRCLK_PIN,
.dout = DATA_OUT_PIN,
.din = DATA_IN_PIN, // In duplex mode, bind output and input to a same gpio can loopback internally
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
}
static void i2s_test_loopback(){
uint8_t *r_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE);
assert(r_buf); // Check if r_buf allocation success
size_t r_bytes = 0;
size_t w_bytes = 0;
while (1) {
/* Read i2s data */
i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000);
printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes);
printf("[0] %x [1] %x [2] %x [3] %x\n[4] %x [5] %x [6] %x [7] %x\n\n",
r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
if (i2s_channel_write(tx_chan, r_buf, EXAMPLE_BUFF_SIZE, &w_bytes, 1000) == ESP_OK) {
printf("Write Task: i2s write %d bytes\n", w_bytes);
} else {
printf("Write Task: i2s write failed\n");
}
}
}
So this works fine, I'm hearing sound from the speaker and this is the output:
Code: Select all
Write Task: i2s write 4096 bytes
Read Task: i2s read 4096 bytes
-----------------------------------
[0] 0 [1] 2a [2] ff [3] ff
[4] 0 [5] 64 [6] 0 [7] 0
Write Task: i2s write 4096 bytes
Read Task: i2s read 4096 bytes
-----------------------------------
[0] 0 [1] a0 [2] a [3] 0
[4] 0 [5] ba [6] 7 [7] 0
Write Task: i2s write 4096 bytes
Read Task: i2s read 4096 bytes
-----------------------------------
[0] 0 [1] 42 [2] 5 [3] 0
[4] 80 [5] d9 [6] 6 [7] 0
So now on to the i2s_stream code:
Code: Select all
void i2s_init(){
ESP_LOGI("i2s_init", "Create reader pipeline");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
pipeline_reader = audio_pipeline_init(&pipeline_cfg);
i2s_std_config_t std_config = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = BCLK_PIN,
.ws = LRCLK_PIN,
.dout = DATA_OUT_PIN,
.din = DATA_IN_PIN,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
i2s_stream_cfg_t i2s_reader_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_reader_cfg.type = AUDIO_STREAM_READER;
i2s_reader_cfg.std_cfg = std_config;
ESP_LOGI("i2s_init", "Configs created, init the reader stream");
i2s_stream_reader = i2s_stream_init(&i2s_reader_cfg);
raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT();
raw_cfg.type = AUDIO_STREAM_READER;
audio_element_handle_t raw_writer = raw_stream_init(&raw_cfg);
ESP_LOGI("i2s_init", "Register all elements to audio pipeline");
audio_pipeline_register(pipeline_reader, i2s_stream_reader, "i2s_read");
audio_pipeline_register(pipeline_reader, raw_writer, "raw");
ESP_LOGI("i2s_init", "Link it together");
const char *link_tag[2] = {"i2s_read", "raw"};
audio_pipeline_link(pipeline_reader, &link_tag[0], 2);
ESP_LOGI("i2s_init", "Run the pipeline");
audio_pipeline_run(pipeline_reader);
char *r_buf = (char *)calloc(1, EXAMPLE_BUFF_SIZE);
assert(r_buf); // Check if r_buf allocation success
while(1){
ESP_LOGI("Pipeline", "Element state: %d %d",
audio_element_get_state(i2s_stream_reader),
audio_element_get_state(raw_writer));
int bytes_read = raw_stream_read(raw_writer, r_buf, EXAMPLE_BUFF_SIZE);
if (bytes_read < 0) {
ESP_LOGE("buf", "Error reading from raw stream");
} else if (bytes_read == 0) {
ESP_LOGW("buf", "End of stream or no data available");
}
printf("[0] %x [1] %x [2] %x [3] %x\n[4] %x [5] %x [6] %x [7] %x\n\n",
r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
vTaskDelay(1000 / portTICK_PERIOD_MS);
};
}
But no joy on the data...:
Code: Select all
I (3114) i2s_init: Create reader pipeline
I (3114) i2s_init: Configs created, init the reader stream
D (3114) i2s_common: rx channel is registered on I2S0 successfully
D (3114) i2s_common: DMA malloc info: dma_desc_num = 3, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = 1248
D (3124) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 39 [mclk] 4096000 Hz [bdiv] 4 [bclk] 1024000 Hz
D (3144) i2s_common: MCLK is pinned to GPIO0 on I2S0
D (3144) i2s_std: The rx channel on I2S0 has been initialized to STD mode successfully
D (3154) i2s_common: i2s rx channel enabled
I (3154) i2s_init: Register all elements to audio pipeline
I (3164) i2s_init: Link it together
I (3164) AUDIO_PIPELINE: link el->rb, el:0x3ffb79dc, tag:i2s_read, rb:0x3ffb921c
I (3174) i2s_init: Run the pipeline
I (3184) AUDIO_THREAD: The i2s_read task allocate stack on internal memory
I (3184) AUDIO_ELEMENT: [i2s_read-0x3ffb79dc] Element task created
I (3194) AUDIO_ELEMENT: [raw-0x3ffb8ea0] Element task created
I (3204) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:270792 Bytes
I (3204) AUDIO_ELEMENT: [i2s_read] AEL_MSG_CMD_RESUME,state:1
I (3214) AUDIO_PIPELINE: Pipeline started
I (3224) Pipeline: Element state: 3 3
[0] 0 [1] 0 [2] 0 [3] 0
[4] 0 [5] 0 [6] 0 [7] 0
I (4284) Pipeline: Element state: 3 3
[0] 0 [1] 0 [2] 0 [3] 0
[4] 0 [5] 0 [6] 0 [7] 0
I (5284) Pipeline: Element state: 3 3
[0] 0 [1] 0 [2] 0 [3] 0
[4] 0 [5] 0 [6] 0 [7] 0
I (6284) Pipeline: Element state: 3 3
[0] 0 [1] 0 [2] 0 [3] 0
[4] 0 [5] 0 [6] 0 [7] 0