| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010 |
- // line 79 - change filter length to adjust echo cancellation
- #include "bsp_board.h"
- #include <stdbool.h>
- #include "esp_err.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
- #include "freertos/task.h"
- #include "string.h"
- #include "driver/gpio.h"
- #include "esp_err.h"
- #include "esp_log.h"
- #include "esp_rom_sys.h"
- #include "esp_check.h"
- #include "esp_vfs_fat.h"
- #include "sdmmc_cmd.h"
- #include "driver/i2s_std.h"
- #include "driver/i2s_types.h"
- #include "driver/i2s_pdm.h"
- #include "driver/i2s_tdm.h"
- #include <sys/unistd.h>
- #include <sys/stat.h>
- #include "dirent.h"
- #include "driver/sdmmc_host.h"
- #include <errno.h>
- #include "esp_aec.h"
- #include "tca9555_driver.h"
- #if ((SOC_SDMMC_HOST_SUPPORTED) && (FUNC_SDMMC_EN))
- #include "driver/sdmmc_host.h"
- #endif /* ((SOC_SDMMC_HOST_SUPPORTED) && (FUNC_SDMMC_EN)) */
- #define ADC_I2S_CHANNEL 2
- #define ADC_BITS_PER_SAMPLE 32
- static sdmmc_card_t *card;
- static const char *TAG = "board";
- static int s_play_sample_rate = 16000;
- static int s_play_channel_format = 1;
- static int s_bits_per_chan = 16;
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- static i2s_chan_handle_t tx_handle = NULL; // I2S tx channel handler
- static i2s_chan_handle_t rx_handle = NULL; // I2S rx channel handler
- #endif
- static audio_codec_data_if_t *record_data_if = NULL;
- static audio_codec_ctrl_if_t *record_ctrl_if = NULL;
- static audio_codec_if_t *record_codec_if = NULL;
- static esp_codec_dev_handle_t record_dev = NULL;
- static audio_codec_data_if_t *play_data_if = NULL;
- static audio_codec_ctrl_if_t *play_ctrl_if = NULL;
- static audio_codec_gpio_if_t *play_gpio_if = NULL;
- static audio_codec_if_t *play_codec_if = NULL;
- static esp_codec_dev_handle_t play_dev = NULL;
- static i2c_master_bus_handle_t i2c_bus_handle = NULL;
- static uint32_t SDCard_Size = 0;
- static bool s_volume_buttons_task_started = false;
- static aec_handle_t *aec = NULL;
- static int frame_size = 0;
- static int16_t *mic = NULL;
- static int16_t *ref = NULL;
- static int16_t *out = NULL;
- static esp_err_t bsp_aec_init(void)
- {
- /* Espressif's direct AEC flow: create, query the algorithm frame size,
- * then allocate aligned signed-16-bit audio buffers for each frame.
- * aec_create_from_config() is used instead of aec_create() so the NLP
- * (residual echo suppression) level can be pushed to its strongest
- * setting; a longer filter_length also helps cancel longer echo tails. */
- aec_config_t aec_cfg = {
- .mic_num = 1,
- .ref_num = 1,
- .out_num = 1,
- .filter_length = 8,
- .sample_rate = 16000,
- .caps = MALLOC_CAP_8BIT,
- .mode = AEC_MODE_VOIP_HIGH_PERF,
- .nlp_level = AEC_NLP_LEVEL_AGGR,
- };
- aec = aec_create_from_config(&aec_cfg);
- if (aec == NULL) {
- ESP_LOGE(TAG, "AEC create failed");
- return ESP_ERR_NO_MEM;
- }
- frame_size = aec_get_chunksize(aec);
- mic = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
- ref = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
- out = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
- if (mic == NULL || ref == NULL || out == NULL) {
- ESP_LOGE(TAG, "AEC buffer allocation failed for %d samples", frame_size);
- free(mic);
- free(ref);
- free(out);
- mic = NULL;
- ref = NULL;
- out = NULL;
- aec_destroy(aec);
- aec = NULL;
- frame_size = 0;
- return ESP_ERR_NO_MEM;
- }
- ESP_LOGI(TAG, "AEC ready: %d samples/frame at 16 kHz", frame_size);
- return ESP_OK;
- }
- static esp_err_t bsp_codec_deinit(void);
- static void bsp_aec_deinit(void)
- {
- if (aec != NULL) {
- aec_destroy(aec);
- aec = NULL;
- }
- free(mic);
- free(ref);
- free(out);
- mic = NULL;
- ref = NULL;
- out = NULL;
- frame_size = 0;
- }
- int bsp_aec_get_frame_size(void)
- {
- return frame_size;
- }
- esp_err_t bsp_aec_process_frame(const int16_t *near_end,
- const int16_t *far_end,
- int16_t *processed)
- {
- if (aec == NULL || mic == NULL || ref == NULL || out == NULL ||
- near_end == NULL || far_end == NULL || processed == NULL) {
- return ESP_ERR_INVALID_STATE;
- }
- memcpy(mic, near_end, frame_size * sizeof(int16_t));
- memcpy(ref, far_end, frame_size * sizeof(int16_t));
- aec_process(aec, mic, ref, out);
- memcpy(processed, out, frame_size * sizeof(int16_t));
- return ESP_OK;
- }
- int mic_level = 0;
- esp_codec_dev_handle_t esp_ret_play_dev(void)
- {
- return play_dev;
- }
- i2c_master_bus_handle_t esp_ret_i2c_handle(void)
- {
- return i2c_bus_handle;
- }
- static esp_err_t i2c_master_init(void)
- {
- const i2c_master_bus_config_t bus_config = {
- .i2c_port = I2C_NUM,
- .sda_io_num = GPIO_I2C_SDA,
- .scl_io_num = GPIO_I2C_SCL,
- .clk_source = I2C_CLK_SRC_DEFAULT,
- };
- esp_err_t ret = i2c_new_master_bus(&bus_config, &i2c_bus_handle);
- if (ret != ESP_OK) {
- ESP_LOGE(TAG, "Failed to initialize I2C bus: %s", esp_err_to_name(ret));
- return ret;
- }
- ESP_LOGI(TAG, "I2C bus initialized successfully");
- return ESP_OK; // 返回 ESP_OK 表示成功
- }
- esp_err_t bsp_codec_adc_init(int sample_rate)
- { ESP_LOGI(TAG,"ADC INIT START");
- esp_err_t ret_val = ESP_OK;
- audio_codec_i2s_cfg_t i2s_cfg = {
- .port = I2S_NUM_1,
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- .rx_handle = rx_handle,
- .tx_handle = NULL,
- #endif
- };
- record_data_if = audio_codec_new_i2s_data(&i2s_cfg);
- if(record_data_if == NULL)
- {
- ESP_LOGE(TAG,"record_data_if creation failed");
- return ESP_FAIL;
- }
- audio_codec_i2c_cfg_t i2c_cfg = {
- .addr = ES7210_CODEC_DEFAULT_ADDR,
- .bus_handle = i2c_bus_handle
- };
- record_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
- es7210_codec_cfg_t es7210_cfg = {
- .ctrl_if = record_ctrl_if,
- /*
- * Microphone initialization for the ES7210 ADC codec.
- * This board supports multiple mic inputs, and the current code enables all
- * 4 available mic channels:
- * MIC1 + MIC2 + MIC3 + MIC4
- *
- * For a 2-mic board, the intended setup is typically to enable only the two
- * physical microphones that are wired to the board, for example:
- * .mic_selected = ES7210_SEL_MIC1 | ES7210_SEL_MIC2;
- *
- * In other words, the current configuration is not "one mic only"; it is
- * configured to allow all entries in the codec, even though the app logic only
- * reads one channel from the resulting stream.
- */
- .mic_selected =
- ES7210_SEL_MIC1 |
- ES7210_SEL_MIC2 |
- ES7210_SEL_MIC3 |
- ES7210_SEL_MIC4,
- };
- record_codec_if = es7210_codec_new(&es7210_cfg);
- ESP_LOGI(TAG,"ES7210 IF=%p", record_codec_if);
- esp_codec_dev_cfg_t dev_cfg = {
- .codec_if = record_codec_if,
- .data_if = record_data_if,
- .dev_type = ESP_CODEC_DEV_TYPE_IN,
- };
- record_dev = esp_codec_dev_new(&dev_cfg);
- if(record_dev == NULL)
- {
- ESP_LOGE(TAG,"Failed creating ADC codec");
- return ESP_FAIL;
- }
- esp_codec_dev_sample_info_t fs = {
- .sample_rate = sample_rate,
- /*
- * Stereo is opened here, which matches a 2-channel mic stream.
- * If the board is wired as a 2-mic stereo pair, the code can use both
- * channels by reading left and right samples from the interleaved buffer.
- * Example:
- * // .mic_selected = ES7210_SEL_MIC1 | ES7210_SEL_MIC2;
- * // left = mic_buffer[i * 2 + 0];
- * // right = mic_buffer[i * 2 + 1];
- */
- .channel = 2,
- .bits_per_sample = 16,
- };
- ret_val = esp_codec_dev_open(record_dev, &fs);
- if(ret_val != ESP_OK)
- {
- ESP_LOGE(TAG,
- "Codec open failed %s",
- esp_err_to_name(ret_val));
- return ret_val;
- }
- esp_codec_dev_set_in_channel_gain(
- record_dev,
- ESP_CODEC_DEV_MAKE_CHANNEL_MASK(0),
- RECORD_VOLUME);
- esp_codec_dev_set_in_channel_gain(
- record_dev,
- ESP_CODEC_DEV_MAKE_CHANNEL_MASK(1),
- RECORD_VOLUME);
- return ret_val;
- }
- esp_err_t bsp_codec_dac_init(int sample_rate, int channel_format, int bits_per_chan)
- {
- esp_err_t ret_val = ESP_OK;
- // Do initialize of related interface: data_if, ctrl_if and gpio_if
- audio_codec_i2s_cfg_t i2s_cfg = {
- .port = I2S_NUM_1,
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- .rx_handle = NULL,
- .tx_handle = tx_handle,
- #endif
- };
- play_data_if = audio_codec_new_i2s_data(&i2s_cfg);
- audio_codec_i2c_cfg_t i2c_cfg = {.addr = ES8311_CODEC_DEFAULT_ADDR,.bus_handle = i2c_bus_handle};
- play_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
- play_gpio_if = audio_codec_new_gpio();
- // New output codec interface
- es8311_codec_cfg_t es8311_cfg = {
- .codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC,
- .ctrl_if = play_ctrl_if,
- .gpio_if = play_gpio_if,
- .pa_pin = GPIO_PWR_CTRL,
- .use_mclk = false,
- };
- play_codec_if = es8311_codec_new(&es8311_cfg);
- // New output codec device
- esp_codec_dev_cfg_t dev_cfg = {
- .codec_if = play_codec_if,
- .data_if = play_data_if,
- .dev_type = ESP_CODEC_DEV_TYPE_OUT,
- };
- play_dev = esp_codec_dev_new(&dev_cfg);
- esp_codec_dev_sample_info_t fs = {
- .bits_per_sample = bits_per_chan,
- .sample_rate = sample_rate,
- .channel = channel_format,
- };
- esp_codec_dev_set_out_vol(play_dev, PLAYER_VOLUME);
- esp_codec_dev_open(play_dev, &fs);
- return ret_val;
- }
- static esp_err_t bsp_codec_adc_deinit()
- {
- esp_err_t ret_val = ESP_OK;
- if (record_dev) {
- esp_codec_dev_close(record_dev);
- esp_codec_dev_delete(record_dev);
- record_dev = NULL;
- }
- // Delete codec interface
- if (record_codec_if) {
- audio_codec_delete_codec_if(record_codec_if);
- record_codec_if = NULL;
- }
-
- // Delete codec control interface
- if (record_ctrl_if) {
- audio_codec_delete_ctrl_if(record_ctrl_if);
- record_ctrl_if = NULL;
- }
-
- // Delete codec data interface
- if (record_data_if) {
- audio_codec_delete_data_if(record_data_if);
- record_data_if = NULL;
- }
- return ret_val;
- }
- static esp_err_t bsp_codec_dac_deinit()
- {
- esp_err_t ret_val = ESP_OK;
- if (play_dev) {
- esp_codec_dev_close(play_dev);
- esp_codec_dev_delete(play_dev);
- play_dev = NULL;
- }
- // Delete codec interface
- if (play_codec_if) {
- audio_codec_delete_codec_if(play_codec_if);
- play_codec_if = NULL;
- }
-
- // Delete codec control interface
- if (play_ctrl_if) {
- audio_codec_delete_ctrl_if(play_ctrl_if);
- play_ctrl_if = NULL;
- }
-
- if (play_gpio_if) {
- audio_codec_delete_gpio_if(play_gpio_if);
- play_gpio_if = NULL;
- }
-
- // Delete codec data interface
- if (play_data_if) {
- audio_codec_delete_data_if(play_data_if);
- play_data_if = NULL;
- }
- return ret_val;
- }
- esp_err_t esp_audio_set_play_vol(int volume)
- {
- if (!play_dev) {
- ESP_LOGE(TAG, "DAC codec init fail");
- return ESP_FAIL;
- }
- esp_codec_dev_set_out_vol(play_dev, volume);
- return ESP_OK;
- }
- esp_err_t esp_audio_get_play_vol(int *volume)
- {
- if (!play_dev) {
- ESP_LOGE(TAG, "DAC codec init fail");
- return ESP_FAIL;
- }
- esp_codec_dev_get_out_vol(play_dev, volume);
- return ESP_OK;
- }
- // static esp_err_t bsp_i2s_init(i2s_port_t i2s_num, uint32_t sample_rate, i2s_channel_fmt_t channel_format, i2s_bits_per_chan_t bits_per_chan)
- static esp_err_t bsp_i2s_init(int i2s_num, uint32_t sample_rate, int channel_format, int bits_per_chan)
- {
- esp_err_t ret_val = ESP_OK;
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- i2s_slot_mode_t channel_fmt = I2S_SLOT_MODE_STEREO;
- if (channel_format == 1) {
- channel_fmt = I2S_SLOT_MODE_MONO;
- } else if (channel_format == 2) {
- channel_fmt = I2S_SLOT_MODE_STEREO;
- } else {
- ESP_LOGE(TAG, "Unable to configure channel_format %d", channel_format);
- channel_format = 1;
- channel_fmt = I2S_SLOT_MODE_MONO;
- }
- if (bits_per_chan != 16 && bits_per_chan != 32) {
- ESP_LOGE(TAG, "Unable to configure bits_per_chan %d", bits_per_chan);
- bits_per_chan = 32;
- }
- i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(i2s_num, I2S_ROLE_MASTER);
- ret_val |= i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle);
- i2s_std_config_t std_cfg = I2S_CONFIG_DEFAULT(sample_rate, channel_fmt, bits_per_chan);
- ret_val |= i2s_channel_init_std_mode(tx_handle, &std_cfg);
- ret_val |= i2s_channel_init_std_mode(rx_handle, &std_cfg);
- ret_val |= i2s_channel_enable(tx_handle);
- ret_val |= i2s_channel_enable(rx_handle);
- #else
- i2s_channel_fmt_t channel_fmt = I2S_CHANNEL_FMT_RIGHT_LEFT;
- if (channel_format == 1) {
- channel_fmt = I2S_CHANNEL_FMT_ONLY_LEFT;
- } else if (channel_format == 2) {
- channel_fmt = I2S_CHANNEL_FMT_RIGHT_LEFT;
- } else {
- ESP_LOGE(TAG, "Unable to configure channel_format %d", channel_format);
- channel_format = 1;
- channel_fmt = I2S_CHANNEL_FMT_ONLY_LEFT;
- }
- if (bits_per_chan != 16 && bits_per_chan != 32) {
- ESP_LOGE(TAG, "Unable to configure bits_per_chan %d", bits_per_chan);
- bits_per_chan = 16;
- }
- i2s_config_t i2s_config = I2S_CONFIG_DEFAULT(sample_rate, channel_fmt, bits_per_chan);
- i2s_pin_config_t pin_config = {
- .bck_io_num = GPIO_I2S_SCLK,
- .ws_io_num = GPIO_I2S_LRCK,
- .data_out_num = GPIO_I2S_DOUT,
- .data_in_num = GPIO_I2S_SDIN,
- .mck_io_num = GPIO_I2S_MCLK,
- };
- ret_val |= i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
- ret_val |= i2s_set_pin(i2s_num, &pin_config);
- #endif
- return ret_val;
- }
- static esp_err_t bsp_i2s_deinit(int i2s_num)
- {
- esp_err_t ret_val = ESP_OK;
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- if (i2s_num == I2S_NUM_1 && rx_handle) {
- ret_val |= i2s_channel_disable(rx_handle);
- ret_val |= i2s_del_channel(rx_handle);
- rx_handle = NULL;
- } else if (i2s_num == I2S_NUM_0 && tx_handle) {
- ret_val |= i2s_channel_disable(tx_handle);
- ret_val |= i2s_del_channel(tx_handle);
- tx_handle = NULL;
- }
- #else
- ret_val |= i2s_stop(i2s_num);
- ret_val |= i2s_driver_uninstall(i2s_num);
- #endif
- return ret_val;
- }
- static esp_err_t bsp_codec_init(
- int adc_sample_rate,
- int dac_sample_rate,
- int dac_channel_format,
- int dac_bits_per_chan)
- {
- //ESP_LOGE(TAG, "bsp_codec_adc_init START");
- esp_err_t ret;
- ret = bsp_codec_adc_init(adc_sample_rate);
- if(ret != ESP_OK)
- {
- ESP_LOGE(TAG,"ADC init failed: %s",
- esp_err_to_name(ret));
- return ret;
- }
- ret = bsp_codec_dac_init(
- dac_sample_rate,
- dac_channel_format,
- dac_bits_per_chan);
- if(ret != ESP_OK)
- {
- ESP_LOGE(TAG,"DAC init failed: %s",
- esp_err_to_name(ret));
- }
- ret = bsp_aec_init();
- if (ret != ESP_OK) {
- bsp_codec_deinit();
- return ret;
- }
- return ret;
- }
- static esp_err_t bsp_codec_deinit()
- {
- esp_err_t ret_val = ESP_OK;
- ret_val |= bsp_codec_adc_deinit();
- ret_val |= bsp_codec_dac_deinit();
- bsp_aec_deinit();
- return ret_val;
- }
- esp_err_t esp_audio_play(const int16_t* data, int length, uint32_t ticks_to_wait)
- {
- size_t bytes_write = 0;
- esp_err_t ret = ESP_OK;
- if (!play_dev) {
- return ESP_FAIL;
- }
- int out_length= length;
- int audio_time = 1;
- audio_time *= (16000 / s_play_sample_rate);
- audio_time *= (2 / s_play_channel_format);
- int *data_out = NULL;
- if (s_bits_per_chan != 32) {
- out_length = length * 2;
- data_out = malloc(out_length);
- for (int i = 0; i < length / sizeof(int16_t); i++) {
- int ret = data[i];
- data_out[i] = ret << 16;
- }
- }
- int *data_out_1 = NULL;
- if (s_play_channel_format != 2 || s_play_sample_rate != 16000) {
- out_length *= audio_time;
- data_out_1 = malloc(out_length);
- int *tmp_data = NULL;
- if (data_out != NULL) {
- tmp_data = data_out;
- } else {
- tmp_data = (int *)data;
- }
- for (int i = 0; i < out_length / (audio_time * sizeof(int)); i++) {
- for (int j = 0; j < audio_time; j++) {
- data_out_1[audio_time * i + j] = tmp_data[i];
- }
- }
- if (data_out != NULL) {
- free(data_out);
- data_out = NULL;
- }
- }
- if (data_out != NULL) {
- ret = esp_codec_dev_write(play_dev, (void *)data_out, out_length);
- free(data_out);
- } else if (data_out_1 != NULL) {
- ret = esp_codec_dev_write(play_dev, (void *)data_out_1, out_length);
- free(data_out_1);
- } else {
- ret = esp_codec_dev_write(play_dev, (void *)data, length);
- }
- return ret;
- }
- int get_mic_level (void) {
- return mic_level;
- }
- esp_err_t esp_get_feed_data(
- bool is_get_raw_channel,
- int16_t *buffer,
- int buffer_len)
- {
- // ESP_LOGE(TAG, "NEW esp_get_feed_data CALLED");
- if(record_dev == NULL)
- {
- ESP_LOGE(TAG,"record_dev NULL");
- return ESP_ERR_INVALID_STATE;
- }
- // ESP_LOGI(TAG,
- // "read buffer=%p size=%d",
- // buffer,
- // buffer_len);
- esp_err_t ret;
- ret = esp_codec_dev_read(
- record_dev,
- buffer,
- buffer_len);
- // ESP_LOGI(TAG,
- // "codec read ret=%s",
- // esp_err_to_name(ret));
- if(ret != ESP_OK)
- {
- return ret;
- }
- // Check microphone data
- int64_t sum = 0;
- for(int i=0;i<buffer_len/sizeof(int16_t);i++)
- {
- sum += abs(buffer[i]);
- }
- ESP_LOGI(TAG,
- "MIC level=%lld",
- sum/(buffer_len/sizeof(int16_t)));
- return ESP_OK;
- }
- int esp_get_feed_channel(void)
- {
- return ADC_I2S_CHANNEL;
- }
- char* esp_get_input_format(void)
- {
- return "RM";
- }
- static void bsp_volume_buttons_task(void *arg)
- {
- /* K1/K3 are wired through the TCA9555 IO expander, not raw ESP32 GPIOs
- * (GPIO0 is the BOOT/RESET strapping pin, so it must not be used here). */
- int last_key1 = 1;
- int last_key3 = 1;
- while (io_expander == NULL) {
- vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
- }
- while (1) {
- uint32_t mask = 0;
- if (esp_io_expander_get_level(io_expander, KEY_VOLUME_UP_PIN | KEY_VOLUME_DOWN_PIN, &mask) != ESP_OK) {
- vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
- continue;
- }
- int key1 = (mask & KEY_VOLUME_UP_PIN) ? 1 : 0;
- int key3 = (mask & KEY_VOLUME_DOWN_PIN) ? 1 : 0;
- if (key1 == 0 && last_key1 != 0) {
- int current_vol = 0;
- if (esp_audio_get_play_vol(¤t_vol) == ESP_OK) {
- current_vol += VOLUME_STEP;
- if (current_vol > VOLUME_MAX_LEVEL) {
- current_vol = VOLUME_MAX_LEVEL;
- }
- if (esp_audio_set_play_vol(current_vol) == ESP_OK) {
- ESP_LOGI(TAG, "Volume up -> %d", current_vol);
- }
- }
- }
- if (key3 == 0 && last_key3 != 0) {
- int current_vol = 0;
- if (esp_audio_get_play_vol(¤t_vol) == ESP_OK) {
- current_vol -= VOLUME_STEP;
- if (current_vol < VOLUME_MIN_LEVEL) {
- current_vol = VOLUME_MIN_LEVEL;
- }
- if (esp_audio_set_play_vol(current_vol) == ESP_OK) {
- ESP_LOGI(TAG, "Volume down -> %d", current_vol);
- }
- }
- }
- last_key1 = key1;
- last_key3 = key3;
- vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
- }
- }
- static esp_err_t bsp_volume_buttons_init(void)
- {
- if (s_volume_buttons_task_started) {
- return ESP_OK;
- }
- /* K1/K3 input direction is already configured on the TCA9555 expander by
- * tca9555_driver_init(); no direct GPIO configuration is needed here. */
- BaseType_t task_created = xTaskCreate(bsp_volume_buttons_task, "vol_btns", 4096, NULL, 5, NULL);
- if (task_created != pdPASS) {
- return ESP_FAIL;
- }
- s_volume_buttons_task_started = true;
- return ESP_OK;
- }
- esp_err_t esp_board_init(uint32_t sample_rate, int channel_format, int bits_per_chan)
- {
- /*!< Initialize I2C bus, used for audio codec*/
- i2c_master_init();
- s_play_sample_rate = sample_rate;
- if (channel_format != 2 && channel_format != 1) {
- ESP_LOGE(TAG, "Unable to configure channel_format");
- channel_format = 2;
- }
- s_play_channel_format = channel_format;
- if (bits_per_chan != 32 && bits_per_chan != 16) {
- ESP_LOGE(TAG, "Unable to configure bits_per_chan");
- bits_per_chan = 32;
- }
- s_bits_per_chan = bits_per_chan;
- bsp_i2s_init(I2S_NUM_1, 16000, 2, 16);
- // Because record and play use the same i2s.
- esp_err_t codec_ret;
- codec_ret = bsp_codec_init(16000,16000,2,16);
- if(codec_ret != ESP_OK)
- {
- ESP_LOGE(TAG,
- "bsp_codec_init failed: %s",
- esp_err_to_name(codec_ret));
- }
- else
- {
- ESP_LOGI(TAG,"bsp_codec_init OK");
- }
- /* Initialize PA */
- /*gpio_config_t io_conf;
- memset(&io_conf, 0, sizeof(io_conf));
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pin_bit_mask = ((1ULL << GPIO_PWR_CTRL));
- io_conf.pull_down_en = 0;
- io_conf.pull_up_en = 0;
- gpio_config(&io_conf);
- */
- gpio_set_level(GPIO_PWR_CTRL, 1);
- esp_err_t button_ret = bsp_volume_buttons_init();
- if (button_ret != ESP_OK) {
- ESP_LOGW(TAG, "Failed to initialize volume buttons: %s", esp_err_to_name(button_ret));
- }
- return ESP_OK;
- }
- esp_err_t esp_sdcard_init(char *mount_point, size_t max_files)
- {
- if (NULL != card) {
- return ESP_ERR_INVALID_STATE;
- }
- /* Check if SD crad is supported */
- if (!FUNC_SDMMC_EN && !FUNC_SDSPI_EN) {
- ESP_LOGE(TAG, "SDMMC and SDSPI not supported on this board!");
- return ESP_ERR_NOT_SUPPORTED;
- }
- esp_err_t ret_val = ESP_OK;
- /**
- * @brief Options for mounting the filesystem.
- * If format_if_mount_failed is set to true, SD card will be partitioned and
- * formatted in case when mounting fails.
- *
- */
- esp_vfs_fat_sdmmc_mount_config_t mount_config = {
- .format_if_mount_failed = false,
- .max_files = max_files,
- .allocation_unit_size = 16 * 1024
- };
- /**
- * @brief Use settings defined above to initialize SD card and mount FAT filesystem.
- * Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
- * Please check its source code and implement error recovery when developing
- * production applications.
- *
- */
- sdmmc_host_t host =
- #if FUNC_SDMMC_EN
- SDMMC_HOST_DEFAULT();
- #else
- SDSPI_HOST_DEFAULT();
- spi_bus_config_t bus_cfg = {
- .mosi_io_num = GPIO_SDSPI_MOSI,
- .miso_io_num = GPIO_SDSPI_MISO,
- .sclk_io_num = GPIO_SDSPI_SCLK,
- .quadwp_io_num = GPIO_NUM_NC,
- .quadhd_io_num = GPIO_NUM_NC,
- .max_transfer_sz = 4000,
- };
- ret_val = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CH_AUTO);
- if (ret_val != ESP_OK) {
- ESP_LOGE(TAG, "Failed to initialize bus.");
- return ret_val;
- }
- #endif
- /**
- * @brief This initializes the slot without card detect (CD) and write protect (WP) signals.
- * Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
- *
- */
- #if FUNC_SDMMC_EN
- sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
- #else
- sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
- #endif
- #if FUNC_SDMMC_EN
- /* Config SD data width. 0, 4 or 8. Currently for SD card, 8 bit is not supported. */
- slot_config.width = SDMMC_BUS_WIDTH;
- /**
- * @brief On chips where the GPIOs used for SD card can be configured, set them in
- * the slot_config structure.
- *
- */
- #if SOC_SDMMC_USE_GPIO_MATRIX
- slot_config.clk = GPIO_SDMMC_CLK;
- slot_config.cmd = GPIO_SDMMC_CMD;
- slot_config.d0 = GPIO_SDMMC_D0;
- slot_config.d1 = GPIO_SDMMC_D1;
- slot_config.d2 = GPIO_SDMMC_D2;
- slot_config.d3 = GPIO_SDMMC_D3;
- #endif
- slot_config.cd = GPIO_SDMMC_DET;
- slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
- #else
- slot_config.gpio_cs = GPIO_SDSPI_CS;
- slot_config.host_id = host.slot;
- #endif
- /**
- * @brief Enable internal pullups on enabled pins. The internal pullups
- * are insufficient however, please make sure 10k external pullups are
- * connected on the bus. This is for debug / example purpose only.
- */
- /* get FAT filesystem on SD card registered in VFS. */
- ret_val =
- #if FUNC_SDMMC_EN
- esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
- #else
- esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
- #endif
- /* Check for SDMMC mount result. */
- if (ret_val != ESP_OK) {
- if (ret_val == ESP_FAIL) {
- ESP_LOGE(TAG, "Failed to mount filesystem. "
- "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
- } else {
- ESP_LOGE(TAG, "Failed to initialize the card (%s). "
- "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret_val));
- }
- return ret_val;
- }
- /* Card has been initialized, print its properties. */
- sdmmc_card_print_info(stdout, card);
- SDCard_Size = ((uint64_t) card->csd.capacity) * card->csd.sector_size / (1024 * 1024);
- return ret_val;
- }
- esp_err_t esp_sdcard_deinit(char *mount_point)
- {
- if (NULL == mount_point) {
- return ESP_ERR_INVALID_STATE;
- }
- /* Unmount an SD card from the FAT filesystem and release resources acquired */
- esp_err_t ret_val = esp_vfs_fat_sdcard_unmount(mount_point, card);
- /* Make SD/MMC card information structure pointer NULL */
- card = NULL;
- return ret_val;
- }
- #define MOUNT_POINT "/sdcard"
- static const char *SD_TAG = "SD";
- uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][MAX_FILE_NAME_SIZE], uint16_t maxFiles)
- {
- DIR *dir = opendir(directory);
- if (dir == NULL) {
- ESP_LOGE(SD_TAG, "Path: <%s> does not exist", directory);
- return 0;
- }
- uint16_t fileCount = 0;
- struct dirent *entry;
- while ((entry = readdir(dir)) != NULL && fileCount < maxFiles) {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
- continue;
- }
- const char *dot = strrchr(entry->d_name, '.');
- if (dot != NULL && dot != entry->d_name) {
- if (strcasecmp(dot, fileExtension) == 0) {
- strncpy(File_Name[fileCount], entry->d_name, MAX_FILE_NAME_SIZE - 1);
- File_Name[fileCount][MAX_FILE_NAME_SIZE - 1] = '\0';
- char filePath[MAX_PATH_SIZE];
- snprintf(filePath, MAX_PATH_SIZE, "%s/%s", directory, entry->d_name);
- printf("File found: %s\r\n", filePath);
- fileCount++;
- }
- }
- else{
-
- // printf("No extension found for file: %s\r\n", entry->d_name);
- }
- }
- closedir(dir);
- if (fileCount > 0) {
- ESP_LOGI(SD_TAG, "Retrieved %d files with extension '%s'", fileCount, fileExtension);
- } else {
- ESP_LOGW(SD_TAG, "No files with extension '%s' found in directory: %s", fileExtension, directory);
- }
- return fileCount;
- }
|