[i2s_audio] Microphone reads in loop for callbacks shouldn't ever delay (#8625)

This commit is contained in:
Kevin Ahrendt 2025-04-27 18:19:01 -05:00 committed by GitHub
parent adcd6517db
commit e557bca420
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 7 deletions

View File

@ -284,19 +284,21 @@ void I2SAudioMicrophone::stop_() {
this->status_clear_error();
}
size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) {
size_t I2SAudioMicrophone::read(int16_t *buf, size_t len, TickType_t ticks_to_wait) {
size_t bytes_read = 0;
#ifdef USE_I2S_LEGACY
esp_err_t err = i2s_read(this->parent_->get_port(), buf, len, &bytes_read, (100 / portTICK_PERIOD_MS));
esp_err_t err = i2s_read(this->parent_->get_port(), buf, len, &bytes_read, ticks_to_wait);
#else
esp_err_t err = i2s_channel_read(this->rx_handle_, buf, len, &bytes_read, (100 / portTICK_PERIOD_MS));
// i2s_channel_read expects the timeout value in ms, not ticks
esp_err_t err = i2s_channel_read(this->rx_handle_, buf, len, &bytes_read, pdTICKS_TO_MS(ticks_to_wait));
#endif
if (err != ESP_OK) {
if ((err != ESP_OK) && ((err != ESP_ERR_TIMEOUT) || (ticks_to_wait != 0))) {
// Ignore ESP_ERR_TIMEOUT if ticks_to_wait = 0, as it will read the data on the next call
ESP_LOGW(TAG, "Error reading from I2S microphone: %s", esp_err_to_name(err));
this->status_set_warning();
return 0;
}
if (bytes_read == 0) {
if ((bytes_read == 0) && (ticks_to_wait > 0)) {
this->status_set_warning();
return 0;
}
@ -350,7 +352,7 @@ size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) {
void I2SAudioMicrophone::read_() {
std::vector<int16_t> samples;
samples.resize(BUFFER_SIZE);
size_t bytes_read = this->read(samples.data(), BUFFER_SIZE / sizeof(int16_t));
size_t bytes_read = this->read(samples.data(), BUFFER_SIZE * sizeof(int16_t), 0);
samples.resize(bytes_read / sizeof(int16_t));
this->data_callbacks_.call(samples);
}

View File

@ -25,7 +25,8 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
void set_pdm(bool pdm) { this->pdm_ = pdm; }
size_t read(int16_t *buf, size_t len) override;
size_t read(int16_t *buf, size_t len, TickType_t ticks_to_wait);
size_t read(int16_t *buf, size_t len) override { return this->read(buf, len, pdMS_TO_TICKS(100)); }
#ifdef USE_I2S_LEGACY
#if SOC_I2S_SUPPORTS_ADC