Audio conversion (to wav file) from PDM mic output is having loud noise
Posted: Mon Aug 29, 2022 2:53 pm
Hi,
Hope you are doing good.
I am trying to convert PDM mic output data to audible form(means in .wav file by adding wav header). Below is my setup.
Development kit : ESP32-S3-MINI-1
ESP-IDF version : 4.4.1 (stable release) and 5.0
IDF example : i2s_audio_recorder_sdcard (in IDF 4.4.1) and i2s_recorder (in IDF 5.0)
PDM microphone : SPH0641LM4H-1
I am getting PDM mic's output data over terminal via UART(by printing HEX data). And then converting it to ".wav" manually. But when I listen the ".wav" file then audio is having loud noise also and output is also not proper. Below is my testing code (for IDF - 4.4.1 and i2s_audio_recorder_sdcard example).
So please suggest me the proper steps if I am doing anything wrong. I doubt on decimation (while printing HEX data on terminal and then converting it to ".wav" file). Do we need to do proper decimation externally for clear audio? I also tried by adding Biquad-LPF using ESP-DSP library but in this case audio file is having loud noise only.
Any kind of help is extremely appreciated.
Thanks in advance.
Hope you are doing good.
I am trying to convert PDM mic output data to audible form(means in .wav file by adding wav header). Below is my setup.
Development kit : ESP32-S3-MINI-1
ESP-IDF version : 4.4.1 (stable release) and 5.0
IDF example : i2s_audio_recorder_sdcard (in IDF 4.4.1) and i2s_recorder (in IDF 5.0)
PDM microphone : SPH0641LM4H-1
I am getting PDM mic's output data over terminal via UART(by printing HEX data). And then converting it to ".wav" manually. But when I listen the ".wav" file then audio is having loud noise also and output is also not proper. Below is my testing code (for IDF - 4.4.1 and i2s_audio_recorder_sdcard example).
Code: Select all
void record_wav()
{
static uint16_t i2s_readraw_buff[SAMPLE_SIZE];
uint32_t rec_time=2;
int flash_wr_size = 0;
uint32_t flash_rec_time = BYTE_RATE * rec_time;
printf("Record starting now....flash_rec_time = %d!!!!\n", flash_rec_time);
// Start recording
while (flash_wr_size < flash_rec_time) {
// Read the RAW samples from the microphone
i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100);
for (int i=0; i < SAMPLE_SIZE/2; i++)
{
printf("%04x", (uint16_t)i2s_readraw_buff[i]);
}
flash_wr_size += bytes_read;
vTaskDelay(50 / portTICK_PERIOD_MS);
}
while(1){
vTaskDelay(200 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "Recording done...... Uninstalling driver.....!");
ESP_ERROR_CHECK( i2s_driver_uninstall(CONFIG_EXAMPLE_I2S_CH) );
}
void init_microphone(void)
{
// Set the I2S configuration as PDM and 16bits per sample
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM,
.sample_rate = CONFIG_EXAMPLE_SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_MSB,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 64,
.dma_buf_len = 200,
.use_apll = 0,
};
// Set the pinout configuration (set using menuconfig)
i2s_pin_config_t pin_config = {
.mck_io_num = I2S_PIN_NO_CHANGE,
.bck_io_num = I2S_PIN_NO_CHANGE,
.ws_io_num = CONFIG_EXAMPLE_I2S_CLK_GPIO,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = CONFIG_EXAMPLE_I2S_DATA_GPIO,
};
// Call driver installation function before any I2S R/W operation.
ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) );
ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) );
// ESP_ERROR_CHECK(i2s_set_pdm_rx_down_sample(I2S_NUM_0,I2S_PDM_DSR_16S) );
ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, CONFIG_EXAMPLE_SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO) );
}
void lv_tick_task(void *arg)
{
while(1)
{
vTaskDelay((200) / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
ESP_LOGI(TAG, "PDM microphone recording Example start");
// Init the PDM digital microphone
init_microphone();
ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME);
// Start Recording
xTaskCreate(lv_tick_task, "lv_tick_task", 1024, NULL, 1, NULL);
xTaskCreate(record_wav, "i2s_pdm_rx_task", 4096*5, NULL, 5, NULL);
}
Any kind of help is extremely appreciated.
Thanks in advance.