mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(i2s): add turn-on time config for mic recorder example
This commit is contained in:
@@ -42,6 +42,7 @@ idf.py menuconfig
|
|||||||
In the `Example Configuration` menu:
|
In the `Example Configuration` menu:
|
||||||
|
|
||||||
* Use `Microphone type` to select between the digital (PDM) and the analog (ES8389) microphone.
|
* 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:
|
* The configuration menu shown below the mic type is updated automatically:
|
||||||
* `PDM MIC Configuration` — assign the PDM clock and data GPIOs (digital microphone).
|
* `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).
|
* `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
|
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
|
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_META sample_rate=16000 bits_per_sample=16 channels=2 data_size=128000 encoding=base64
|
||||||
AUDIO_BASE64_BEGIN
|
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.
|
* Check the I2C wiring (SDA/SCL) and that `ES8389 Codec Configuration` matches your board.
|
||||||
* Increase `Mic gain (dB)` in the `Example Configuration` menu.
|
* 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.
|
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ menu "Example Configuration"
|
|||||||
select CODEC_ES8389_SUPPORT
|
select CODEC_ES8389_SUPPORT
|
||||||
endchoice
|
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"
|
menu "PDM MIC Configuration"
|
||||||
depends on EXAMPLE_MIC_TYPE_DMIC
|
depends on EXAMPLE_MIC_TYPE_DMIC
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
static void send_pcm_as_base64(const uint8_t *pcm_data, size_t pcm_size)
|
||||||
{
|
{
|
||||||
unsigned char encoded_chunk[EXAMPLE_BASE64_BUFFER_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_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg));
|
||||||
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
|
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);
|
ESP_LOGI(TAG, "Starting PDM recording for %d seconds!", EXAMPLE_RECORD_TIME_SECONDS);
|
||||||
capture_pcm(rx_handle, pcm_data, pcm_size);
|
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_ERROR_CHECK(esp_codec_dev_set_in_gain(codec_handle, CONFIG_EXAMPLE_MIC_GAIN));
|
||||||
ESP_LOGI(TAG, "ES8389 codec initialized");
|
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);
|
ESP_LOGI(TAG, "Starting ES8389 recording for %d seconds!", EXAMPLE_RECORD_TIME_SECONDS);
|
||||||
capture_pcm(rx_handle, pcm_data, pcm_size);
|
capture_pcm(rx_handle, pcm_data, pcm_size);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user