You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
Hello,
I sample an analog microphone with ADC continuous, and push the samples into an I2S output.
The ADC continuous docs mention that it consumes I2S_NUM_0, so I assume it is fully capable of producing correctly aligned samples. However, the following code does not produce correct sound. The pitch in the I2S output can be heard way too high and particularly too fast, as if the sample rates were not aligned. Lowering the I2S sample rate to 16kHz produces better result but yet the audio quality is still very poor as if the frames were not aligned.
I could not find an example in ESP IDF or ESP ADF that demonstrates the sampling of the continuous ADC is reliable.
Is the ESP32 even capable of sampling audio via ADC ? The reason for not using I2S for audio input is that I need to sample more than 3 microphones at the same time and the second I2S port I keep for a speaker.
Here is the code I use:
#include<stdio.h>#include<string.h>#include"driver/i2s_std.h"#include"esp_adc/adc_continuous.h"#include"esp_err.h"#include"esp_log.h"#include"freertos/FreeRTOS.h"#include"freertos/semphr.h"#include"freertos/task.h"#include"sdkconfig.h"#defineEXAMPLE_READ_LEN 256
i2s_chan_handle_ttx_chan=NULL;
staticadc_channel_tchannel[1] = {ADC_CHANNEL_7};
staticTaskHandle_ts_task_handle;
staticconstchar*TAG="EXAMPLE";
staticvoidi2s_init() {
i2s_chan_config_tchan_cfg=I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_MASTER);
chan_cfg.auto_clear= true;
i2s_std_config_tstd_cfg= {
.clk_cfg=I2S_STD_CLK_DEFAULT_CONFIG(20000),
.slot_cfg=I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg= {
.mclk=I2S_GPIO_UNUSED,
.bclk=26,
.ws=25,
.dout=32,
.din=I2S_GPIO_UNUSED,
.invert_flags= {
.mclk_inv= false,
.bclk_inv= false,
.ws_inv= false,
},
},
};
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
}
staticboolIRAM_ATTRs_conv_done_cb(adc_continuous_handle_thandle, constadc_continuous_evt_data_t*edata, void*user_data) {
BaseType_tmustYield=pdFALSE;
// Notify that ADC continuous driver has done enough number of conversionsvTaskNotifyGiveFromISR(s_task_handle, &mustYield);
return (mustYield==pdTRUE);
}
staticvoidcontinuous_adc_init(adc_channel_t*channel, uint8_tchannel_num, adc_continuous_handle_t*out_handle) {
adc_continuous_handle_thandle=NULL;
adc_continuous_handle_cfg_tadc_config= {
.max_store_buf_size=10*1024,
.conv_frame_size=EXAMPLE_READ_LEN,
};
ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle));
adc_continuous_config_tdig_cfg= {
.sample_freq_hz=20000,
.conv_mode=ADC_CONV_SINGLE_UNIT_1,
.format=ADC_DIGI_OUTPUT_FORMAT_TYPE1,
};
adc_digi_pattern_config_tadc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
dig_cfg.pattern_num=channel_num;
for (inti=0; i<channel_num; i++) {
adc_pattern[i].atten=ADC_ATTEN_DB_0;
adc_pattern[i].channel=channel[i] &0x7;
adc_pattern[i].unit=ADC_UNIT_1;
adc_pattern[i].bit_width=SOC_ADC_DIGI_MAX_BITWIDTH;
ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten);
ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel);
ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit);
}
dig_cfg.adc_pattern=adc_pattern;
ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg));
*out_handle=handle;
}
voidapp_main(void) {
i2s_init();
esp_err_tret;
uint32_tret_num=0;
size_tspeaker_bytes_written;
uint8_tresult[EXAMPLE_READ_LEN] __attribute__((aligned(4))) = {0};
uint8_tdata[EXAMPLE_READ_LEN] = {0}; // Buffer for I2S datamemset(result, 0xcc, EXAMPLE_READ_LEN);
s_task_handle=xTaskGetCurrentTaskHandle();
adc_continuous_handle_thandle=NULL;
continuous_adc_init(channel, sizeof(channel) / sizeof(adc_channel_t), &handle);
adc_continuous_evt_cbs_tcbs= {
.on_conv_done=s_conv_done_cb,
};
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL));
ESP_ERROR_CHECK(adc_continuous_start(handle));
while (1) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ret=adc_continuous_read(handle, result, EXAMPLE_READ_LEN, &ret_num, 0);
if (ret!=ESP_OK) {
continue;
}
// Convert ADC samples to byte array for I2Sfor (inti=0; i<ret_num; i+=SOC_ADC_DIGI_RESULT_BYTES) {
adc_digi_output_data_t*p= (adc_digi_output_data_t*)&result[i];
uint16_tadc=p->type1.data;
int16_tsample= ((int16_t)adc-2048) << 4; // Convert to signed 16-bit PCM// Split sample into two bytes and store in the data arraydata[i] =sample&0xFF; // Lower bytedata[i+1] = (sample >> 8) &0xFF; // Upper byte
}
// Write the byte array to the I2S speakeri2s_channel_write(tx_chan, data, ret_num, &speaker_bytes_written, portMAX_DELAY);
// vTaskDelay(1);
}
}
Wishing you the very best, and thanks in advance for pointing out whether ESP-IDF produces reliable and evenly distributed samples in ADC continuous mode.
The text was updated successfully, but these errors were encountered:
github-actionsbot
changed the title
ADC continuous sample rate does not match I2S
ADC continuous sample rate does not match I2S (IDFGH-14457)
Jan 18, 2025
Answers checklist.
General issue report
Hello,
I sample an analog microphone with ADC continuous, and push the samples into an I2S output.
The ADC continuous docs mention that it consumes
I2S_NUM_0
, so I assume it is fully capable of producing correctly aligned samples. However, the following code does not produce correct sound. The pitch in the I2S output can be heard way too high and particularly too fast, as if the sample rates were not aligned. Lowering the I2S sample rate to 16kHz produces better result but yet the audio quality is still very poor as if the frames were not aligned.I could not find an example in ESP IDF or ESP ADF that demonstrates the sampling of the continuous ADC is reliable.
Is the ESP32 even capable of sampling audio via ADC ? The reason for not using I2S for audio input is that I need to sample more than 3 microphones at the same time and the second I2S port I keep for a speaker.
Here is the code I use:
Wishing you the very best, and thanks in advance for pointing out whether ESP-IDF produces reliable and evenly distributed samples in ADC continuous mode.
The text was updated successfully, but these errors were encountered: