feat(i2s): add turn-on time config for mic recorder example

This commit is contained in:
Chen Chen
2026-08-17 15:53:34 +08:00
parent c07cec57ca
commit 91d1a54373
3 changed files with 44 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ idf.py menuconfig
In the `Example Configuration` menu:
* Use `Microphone type` to select between the digital (PDM) and the analog (ES8389) microphone.
* Use `Startup data to discard (ms)` to drop the first N milliseconds of PCM after the microphone path is running. The default is 20 ms. Set it to 0 to keep every sample. Refer to the microphone datasheet for the startup delay (also called turn-on time).
* The configuration menu shown below the mic type is updated automatically:
* `PDM MIC Configuration` — assign the PDM clock and data GPIOs (digital microphone).
* `ES8389 Codec Configuration` — assign the I2C and I2S GPIOs, plus the mic gain (analog microphone).
@@ -71,7 +72,7 @@ A digital-microphone run looks like:
```
PDM MIC recording example start
--------------------------------------
I (...) mic_rec_example: Starting recording for 2 seconds!
I (...) mic_rec_example: Starting PDM recording for 2 seconds!
I (...) mic_rec_example: Recording done, sending PCM data over console
AUDIO_META sample_rate=16000 bits_per_sample=16 channels=2 data_size=128000 encoding=base64
AUDIO_BASE64_BEGIN
@@ -123,4 +124,9 @@ Open it with [Audacity](https://www.audacityteam.org/) to listen to the recordin
* Check the I2C wiring (SDA/SCL) and that `ES8389 Codec Configuration` matches your board.
* Increase `Mic gain (dB)` in the `Example Configuration` menu.
* Recording starts with a pop, click, or a short stretch of invalid audio
* Increase `Startup data to discard (ms)` in the `Example Configuration` menu. The stored recording length stays the same.
* Refer to the microphone datasheet for the startup delay (also called turn-on time).
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -24,6 +24,18 @@ menu "Example Configuration"
select CODEC_ES8389_SUPPORT
endchoice
config EXAMPLE_STARTUP_DISCARD_MS
int "Startup data to discard (ms)"
default 20
range 0 500
help
Number of milliseconds of PCM to read and discard after the
microphone path is running, before the recording is stored.
Use this to skip the microphone or codec startup transient.
The default is 20 ms. Set to 0 to keep every sample.
Refer to the microphone datasheet for the startup delay
(also called turn-on time).
menu "PDM MIC Configuration"
depends on EXAMPLE_MIC_TYPE_DMIC

View File

@@ -57,6 +57,27 @@ static void capture_pcm(i2s_chan_handle_t rx_handle, uint8_t *pcm_data, size_t p
}
}
static void discard_startup_pcm(i2s_chan_handle_t rx_handle)
{
const size_t bytes_to_discard = (size_t)EXAMPLE_SAMPLE_RATE * EXAMPLE_CHANNEL_COUNT *
(EXAMPLE_BITS_PER_SAMPLE / 8) * CONFIG_EXAMPLE_STARTUP_DISCARD_MS / 1000;
if (bytes_to_discard == 0) {
return;
}
uint8_t discard_buf[EXAMPLE_DMA_READ_SIZE];
size_t bytes_discarded = 0;
ESP_LOGI(TAG, "Discarding the first %d ms of startup data", CONFIG_EXAMPLE_STARTUP_DISCARD_MS);
while (bytes_discarded < bytes_to_discard) {
size_t bytes_to_read = bytes_to_discard - bytes_discarded;
bytes_to_read = MIN(bytes_to_read, EXAMPLE_DMA_READ_SIZE);
size_t bytes_read = 0;
ESP_ERROR_CHECK(i2s_channel_read(rx_handle, discard_buf, bytes_to_read, &bytes_read, 1000));
bytes_discarded += bytes_read;
}
}
static void send_pcm_as_base64(const uint8_t *pcm_data, size_t pcm_size)
{
unsigned char encoded_chunk[EXAMPLE_BASE64_BUFFER_SIZE];
@@ -100,6 +121,8 @@ static void record_from_pdm_microphone(uint8_t *pcm_data, size_t pcm_size)
ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
/* Discard the startup PCM to skip the microphone startup transient. */
discard_startup_pcm(rx_handle);
ESP_LOGI(TAG, "Starting PDM recording for %d seconds!", EXAMPLE_RECORD_TIME_SECONDS);
capture_pcm(rx_handle, pcm_data, pcm_size);
@@ -191,6 +214,8 @@ static void record_from_es8389_microphone(uint8_t *pcm_data, size_t pcm_size)
ESP_ERROR_CHECK(esp_codec_dev_set_in_gain(codec_handle, CONFIG_EXAMPLE_MIC_GAIN));
ESP_LOGI(TAG, "ES8389 codec initialized");
/* Discard the startup PCM to skip the microphone or codec startup transient. */
discard_startup_pcm(rx_handle);
ESP_LOGI(TAG, "Starting ES8389 recording for %d seconds!", EXAMPLE_RECORD_TIME_SECONDS);
capture_pcm(rx_handle, pcm_data, pcm_size);