espressif / esp-adf

Espressif Audio Development Framework
Other
1.52k stars 669 forks source link

error while running in esp32 (AUD-4822) and wifi is getting disconnected #1056

Closed be-inexplicable closed 1 year ago

be-inexplicable commented 1 year ago

---- Opened the serial port COM5 ---- ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x1f (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:7432 load:0x40078000,len:16564 load:0x40080400,len:4 load:0x40080404,len:4284 entry 0x40080668 I (29) boot: ESP-IDF v5.1-dirty 2nd stage bootloader I (29) boot: compile time Aug 15 2023 10:02:55 I (29) boot: Multicore bootloader I (34) boot: chip revision: v3.0 I (38) qio_mode: Enabling default flash chip QIO I (43) boot.esp32: SPI Speed : 80MHz I (48) boot.esp32: SPI Mode : QIO I (52) boot.esp32: SPI Flash Size : 8MB I (57) boot: Enabling RNG early entropy source... I (62) boot: Partition Table: I (66) boot: ## Label Usage Type ST Offset Length I (73) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (80) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (88) boot: 2 factory factory app 00 00 00010000 00500000 I (95) boot: End of partition table I (100) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=649f4h (412148) map I (157) esp_image: segment 1: paddr=00074a1c vaddr=3ff80066 size=00008h ( 8) load I (158) esp_image: segment 2: paddr=00074a2c vaddr=3ffb0000 size=04390h ( 17296) load I (166) esp_image: segment 3: paddr=00078dc4 vaddr=40080000 size=07254h ( 29268) load I (177) esp_image: segment 4: paddr=00080020 vaddr=400d0020 size=d7148h (880968) map I (286) esp_image: segment 5: paddr=00157170 vaddr=40087254 size=16de8h ( 93672) load I (302) esp_image: segment 6: paddr=0016df60 vaddr=400c0000 size=00068h ( 104) load I (317) boot: Loaded app from partition at offset 0x10000 I (317) boot: Disabling RNG early entropy source... I (329) cpu_start: Multicore app I (329) quad_psram: This chip is ESP32-D0WD I (330) esp_psram: Found 8MB PSRAM device I (331) esp_psram: Speed: 80MHz I (335) esp_psram: PSRAM initialized, cache is in low/high (2-core) mode. W (342) esp_psram: Virtual address not enough for PSRAM, map as much as we can. 4MB is mapped I (352) cpu_start: Pro cpu up. I (355) cpu_start: Starting app cpu, entry point is 0x40081ec8 I (0) cpu_start: App cpu up. I (876) esp_psram: SPI SRAM memory test OK I (884) cpu_start: Pro cpu start user code I (884) cpu_start: cpu freq: 240000000 Hz I (884) cpu_start: Application information: I (887) cpu_start: Project name: toy1 I (891) cpu_start: App version: 1 I (896) cpu_start: Compile time: Aug 15 2023 10:01:28 I (902) cpu_start: ELF file SHA256: 063fe588ef174378... I (908) cpu_start: ESP-IDF: v5.1-dirty I (913) cpu_start: Min chip rev: v0.0 I (918) cpu_start: Max chip rev: v3.99 I (923) cpu_start: Chip rev: v3.0 I (927) heap_init: Initializing. RAM available for dynamic allocation: I (935) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (941) heap_init: At 3FFB94B0 len 00026B50 (154 KiB): DRAM I (947) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (953) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (960) heap_init: At 4009E03C len 00001FC4 (7 KiB): IRAM I (966) esp_psram: Adding pool of 4096K of PSRAM memory to heap allocator I (974) spi_flash: detected chip: gd I (977) spi_flash: flash io: qio W (981) ADC: legacy driver is deprecated, please migrate to esp_adc/adc_oneshot.h W (990) i2s(legacy): legacy i2s driver is deprecated, please migrate to use driver/i2s_std.h, driver/i2s_pdm.h or driver/i2s_tdm.h I (1002) app_start: Starting scheduler on CPU0 I (1007) app_start: Starting scheduler on CPU1 I (1007) main_task: Started on CPU0 I (1017) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations I (1025) main_task: Calling app_main() I (1029) MODE_SELECTION: [ 1 ] nvs flash I (1062) MODE_SELECTION: [ 2 ] Start codec chip E (1083) gpio: gpio_install_isr_service(498): GPIO isr service already installed I (1083) MODE_SELECTION: [3.1] Initialize keys on board I (1086) MODE_SELECTION: [ 3 ] Start and wait for Wi-Fi network I (1093) MODE_SELECTION: [4] Mount sdcard W (1112) PERIPH_TOUCH: _touch_init I (1742) MODE_SELECTION: [ 5 ] Create and start input key service I (1742) MODE_SELECTION: [ 5 ] mode selection W (3078) PERIPH_WIFI: WiFi Event cb, Unhandle event_base:WIFI_EVENT, event_id:4 I (4579) MODE_SELECTION: Waiting for mode selection for 300 seconds... W (17175) AUDIO_EVT: There is no space in external queue CMakeLists.txt partitions.csv

----------------------------- code----------------------------- `

include

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "freertos/queue.h"

include "esp_log.h"

include "esp_http_client.h"

include "esp_peripherals.h"

include "periph_sdcard.h"

include "audio_pipeline.h"

include "audio_element.h"

include "audio_event_iface.h"

include "audio_common.h"

include "fatfs_stream.h"

include "i2s_stream.h"

include "http_stream.h"

include "esp_adc/adc_oneshot.h"

include "periph_wifi.h"

include "raw_stream.h"

include "mp3_decoder.h"

include "audio_mem.h"

include "driver/gpio.h"

include

include "board.h"

include "driver/i2s_std.h"

include "sdkconfig.h"

include "wav_encoder.h"

include "wav_decoder.h"

include "esp_wifi.h"

include "wifi_service.h"

include "periph_adc_button.h"

include "input_key_service.h"

include "esp_idf_version.h"

include "esp_err.h"

include "nvs_flash.h"

include

if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0))

include "esp_netif.h"

endif

define RECORD_TIME_SECONDS (120) // 2 minutes in seconds

define HTTP_MAX_TIME_SECONDS (300) // 5 minutes in seconds

define HTTP_MAX_SIZE_BYTES (15 1024 1024) // 15 MB in bytes

define AUDIO_SAMPLE_RATE (16000)

static const char *TAG = "MODE_SELECTION";

define CONFIG_WIFI_SSID "Pixel_2261"

define CONFIG_WIFI_PASSWORD "123412341234"

define MODE_SELECTION_TIMEOUT_SECONDS (5 * 60) // 5 minutes in seconds

define SLEEP_TIMEOUT_SECONDS (5 * 60) // 5 minutes in seconds

audio_element_handle_t i2s_stream_reader, fatfs_stream_writer, wav_encoder, fatfs_stream_reader, http_stream_reader,i2s_stream_writer,wav_decoder,mp3_decoder; esp_periph_set_handle_t set; audio_event_iface_msg_t msg; esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); static bool is_recording = false; static bool is_playing_sd = false; static bool is_playing_http = false;

bool toogle_switch=false; bool r= false; int mode = 1; const char filename; const char pipeline; const char *element; enum wifi_service_event_t;

static void record_audio(void); static void play_from_http(void); static void play_from_sd_card(const char *filename); void wait_for_mode_selection(void);

//** const int NUM_MODES = 3; //** void app_main(void) {

esp_log_level_set("*", ESP_LOG_WARN);
esp_log_level_set(TAG, ESP_LOG_INFO);

ESP_LOGI(TAG, "[ 1 ] nvs flash");
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
    ESP_ERROR_CHECK(nvs_flash_erase());
    err = nvs_flash_init();
}
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0))
ESP_ERROR_CHECK(esp_netif_init());
#endif

ESP_LOGI(TAG, "[ 2 ] Start codec chip");
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);

esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);

ESP_LOGI(TAG, "[3.1] Initialize keys on board");
audio_board_key_init(set);

ESP_LOGI(TAG, "[ 3 ] Start and wait for Wi-Fi network");

 periph_wifi_cfg_t wifi_cfg = {
    .ssid = CONFIG_WIFI_SSID,
    .password = CONFIG_WIFI_PASSWORD,
};
esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg);;
esp_periph_start(set, wifi_handle);
wifi_connect();
periph_wifi_wait_for_connected(wifi_handle,1000/portMAX_DELAY);

if (periph_wifi_is_connected(wifi_handle) == PERIPH_WIFI_CONNECTED) {
    r=true;}
    else{r=false;}

ESP_LOGI(TAG, "[4] Mount sdcard");
// Initialize SD Card peripheral
audio_board_sdcard_init(set, SD_MODE_1_LINE);

 ESP_LOGI(TAG, "[ 5 ] Create and start input key service");
 audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();  
audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);
audio_event_iface_msg_t msg;
ESP_LOGI(TAG, "[ 5 ] mode selection");
 if (audio_event_iface_listen(evt, &msg, portMAX_DELAY) == ESP_OK) {
    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && (msg.cmd == PERIPH_ADC_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)){         
              // Cycle through modes
             // Update mode based on current mode index
            mode = (mode + 1) % NUM_MODES;
           switch (mode) {
            case 1:if (r==true) {
                        is_recording = false;
                        is_playing_sd = false;
                        is_playing_http = true;
                        play_from_http();
                        ESP_LOGI(TAG, "Selected mode: Play from HTTP");
                    } else {
                        is_recording = false;
                        is_playing_sd = true;
                        is_playing_http = false;
                        play_from_sd_card( "/sdcard/httpmusic.mp3"); // Replace with the appropriate SD card filename
                        ESP_LOGI(TAG, "Selected mode: Play from SD Card (Wi-Fi not connected)");
                    }
                    break;
            case 2:
                    is_recording = true;
                    is_playing_sd = false;
                    is_playing_http = false;
                    record_audio();
                    ESP_LOGI(TAG, "Selected mode: Audio Recording");
                    break;
            case 3:
                    is_recording = false;
                    is_playing_sd = true;
                    is_playing_http = false;
                    play_from_sd_card("/sdcard/rec.wav");
                    ESP_LOGI(TAG, "Selected mode: Play from SD Card");
                    break;
            default:
                    is_recording = false;
                    is_playing_sd = true;
                    is_playing_http = false;
                    play_from_sd_card("/sdcard/rec.wav");
                    ESP_LOGI(TAG, "Selected mode: Play from SD Card");
                    break;

                    }
    }
}

wait_for_mode_selection();

// Release all resources
ESP_LOGI(TAG, "[7] terminating everything");

audio_element_deinit(i2s_stream_reader);
audio_element_deinit(i2s_stream_writer);
audio_element_deinit(http_stream_reader);
audio_element_deinit(mp3_decoder);
audio_element_deinit(wav_encoder);
audio_element_deinit(wav_decoder);
audio_element_deinit(fatfs_stream_writer);
audio_element_deinit(fatfs_stream_reader);

} //** //** static void record_audio(void) { is_recording = true;

audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
audio_pipeline_handle_t rec_pipeline = audio_pipeline_init(&pipeline_cfg);
mem_assert(rec_pipeline);

// Create I2S stream to read audio data from codec chip i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); i2s_cfg.type = AUDIO_STREAM_READER; i2s_cfg.i2s_config.sample_rate = AUDIO_SAMPLE_RATE; i2s_stream_reader = i2s_stream_init(&i2s_cfg);

// Create WAV encoder to encode audio data in WAV format wav_encoder_cfg_t wav_cfg = DEFAULT_WAV_ENCODER_CONFIG(); // You need to replace this with the actual function for initializing the WAV encoder audio_element_handle_t wav_encoder = wav_encoder_init(&wav_cfg);

// Create FATFS stream to write WAV data to SD card ESP_LOGI(TAG, "[3.1] Create fatfs stream to write data to sdcard"); fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT(); fatfs_cfg.type = AUDIO_STREAM_WRITER; fatfs_stream_writer = fatfs_stream_init(&fatfs_cfg);

// Register all elements to the audio pipeline audio_pipeline_register(rec_pipeline, i2s_stream_reader, "i2s"); audio_pipeline_register(rec_pipeline, wav_encoder, "wav"); // Update the tag to "wav" audio_pipeline_register(rec_pipeline, fatfs_stream_writer, "file");

// Link elements together: [codec_chip]-->i2s_stream-->filter-->wav_encoder-->fatfs_stream-->[sdcard] const char *link_tag[4] = {"i2s", "wav", "file"}; // Update the tag to "wav" audio_pipeline_link(rec_pipeline, &link_tag[0], 3);

ESP_LOGI(TAG, "[3.6] Set music info to fatfs"); audio_element_info_t music_info = {0}; audio_element_getinfo(i2s_stream_reader, &music_info); ESP_LOGI(TAG, "[ * ] Save the recording info to the fatfs stream writer, sample_rates=%d, bits=%d, ch=%d", music_info.sample_rates, music_info.bits, music_info.channels); audio_element_setinfo(fatfs_stream_writer, &music_info);

audio_element_set_uri(fatfs_stream_writer, "/sdcard/rec.wav");

ESP_LOGI(TAG, "[ 1] Set up event listener"); audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);

ESP_LOGI(TAG, "[1.1] Listening event from pipeline"); audio_pipeline_set_listener(rec_pipeline, evt);

ESP_LOGI(TAG, "[1.2] Listening event from peripherals"); audio_event_iface_set_listener(esp_periph_set_get_event_iface( set), evt);

while (true) {

    esp_err_t ret = audio_event_iface_listen(evt, &msg, 0);  // Non-blocking read
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Error reading event from queue: %d", ret);
        break;
    }
}
ESP_LOGI(TAG, "Event listener queue cleared");

// Start audio pipeline audio_pipeline_run(rec_pipeline);

ESP_LOGI(TAG, "[ 1.3 ] Listen for all pipeline events, record for %d Seconds", RECORD_TIME_SECONDS); int second_recorded = 0; while (1) { if (audio_event_iface_listen(evt, &msg, 1000 / portTICK_RATE_MS) != ESP_OK) { second_recorded ++; ESP_LOGI(TAG, "[ ] Recording ... %d", second_recorded); if (second_recorded >= RECORD_TIME_SECONDS) { audio_element_set_ringbuf_done(i2s_stream_reader); } continue; } / Stop when the last pipeline element (fatfs_stream_writer in this case) receives stop event / if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void ) fatfs_stream_writer && msg.cmd == AEL_MSG_CMD_REPORT_STATUS && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED) || ((int)msg.data == AEL_STATUS_ERROR_OPEN))) { ESP_LOGW(TAG, "[ ] Stop event received"); break; } /pause or play button*/ if (((int)msg.data == get_input_play_id()) && (msg.cmd == PERIPH_ADC_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)) { toogle_switch = !toogle_switch; audio_pipeline_pause(rec_pipeline); ESP_LOGE(TAG, ""); if (toogle_switch) { audio_pipeline_pause(rec_pipeline); } else { audio_pipeline_resume(rec_pipeline); } audio_pipeline_run(rec_pipeline); ESP_LOGE(TAG, "[ 4.1 ] Start playback new pipeline"); } }

is_recording = false; audio_pipeline_stop(rec_pipeline); audio_pipeline_wait_for_stop(rec_pipeline); audio_pipeline_terminate(rec_pipeline); audio_pipeline_unregister(rec_pipeline, i2s_stream_reader); audio_pipeline_unregister(rec_pipeline, wav_encoder); audio_pipeline_unregister(rec_pipeline, fatfs_stream_writer); audio_pipeline_remove_listener(rec_pipeline); audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt); audio_event_iface_destroy(evt); audio_pipeline_deinit(rec_pipeline); vTaskDelete(NULL); } //** static void play_from_sd_card(const char *filename){

is_playing_sd = true; ESP_LOGI(TAG, "[3.1] Create fatfs stream to read data from SD card"); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); audio_pipeline_handle_t sd_pipeline = audio_pipeline_init(&pipeline_cfg); mem_assert(sd_pipeline);

ESP_LOGI(TAG, "[3.1] Create fatfs stream to read data from SD card"); fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT(); fatfs_cfg.type = AUDIO_STREAM_READER; fatfs_stream_reader = fatfs_stream_init(&fatfs_cfg);

ESP_LOGI(TAG, "[3.2] Create i2s stream to write data to codec chip"); i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); i2s_cfg.type = AUDIO_STREAM_WRITER; i2s_stream_writer = i2s_stream_init(&i2s_cfg);

ESP_LOGI(TAG, "[3.3] Create wav decoder"); wav_decoder_cfg_t wav_dec_cfg = DEFAULT_WAV_DECODER_CONFIG(); audio_element_handle_t wav_decoder = wav_decoder_init(&wav_dec_cfg);

ESP_LOGI(TAG, "[3.4] Register all elements to audio pipeline"); audio_pipeline_register(sd_pipeline, fatfs_stream_reader, "file"); audio_pipeline_register(sd_pipeline, wav_decoder, "wav"); audio_pipeline_register(sd_pipeline, i2s_stream_writer, "i2s");

ESP_LOGI(TAG, "[3.5] Link elements together: [sdcard]-->fatfs_stream-->wav_decoder-->i2s_stream-->[codec_chip]"); const char *link_tag[3] = {"file", "wav", "i2s"}; audio_pipeline_link(sd_pipeline, &link_tag[0], 3);

ESP_LOGI(TAG, "[3.6] Set up uri:test.wav"); audio_element_set_uri(fatfs_stream_reader, filename);

ESP_LOGI(TAG, "[3.6] Set up event listener"); audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); audio_pipeline_set_listener(sd_pipeline, evt); ESP_LOGI(TAG, "[1.2] Listening event from peripherals"); audio_event_iface_set_listener(esp_periph_set_get_event_iface( set), evt);

ESP_LOGI(TAG, "[3.7] Start audio pipeline"); audio_pipeline_run(sd_pipeline);

ESP_LOGI(TAG, "[ 6 ] Listen for all pipeline events"); while (1) { audio_event_iface_msg_t msg; esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); if (ret != ESP_OK) { ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); continue; }

    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) wav_decoder
        && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
        audio_element_info_t music_info = {0};
        audio_element_getinfo(wav_decoder, &music_info);

        ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
                 music_info.sample_rates, music_info.bits, music_info.channels);

        audio_element_setinfo(i2s_stream_writer, &music_info);
        i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels);
        continue;
    }

    /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */
    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer
        && msg.cmd == AEL_MSG_CMD_REPORT_STATUS
        && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) {
        ESP_LOGW(TAG, "[ * ] Stop event received");
        break;
    }
    /*play puase button*/

     if (((int)msg.data == get_input_play_id()) && (msg.cmd == PERIPH_ADC_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)) {
        toogle_switch = !toogle_switch;
        audio_pipeline_pause(sd_pipeline);
        ESP_LOGE(TAG,  "");
        if (toogle_switch) {
           audio_pipeline_pause(sd_pipeline);
        } else {
            audio_pipeline_resume(sd_pipeline);
        }
        audio_pipeline_run(sd_pipeline);
        ESP_LOGE(TAG, "[ 4.1 ] Start playback new pipeline");
    }
}

is_playing_sd = false;
ESP_LOGI(TAG, "[4.0] Stop audio pipeline");
audio_pipeline_stop(sd_pipeline);
audio_pipeline_wait_for_stop(sd_pipeline);
audio_pipeline_terminate(sd_pipeline);
audio_pipeline_unregister(sd_pipeline, fatfs_stream_reader);
audio_pipeline_unregister(sd_pipeline,wav_decoder);
audio_pipeline_unregister(sd_pipeline, i2s_stream_writer);
audio_pipeline_remove_listener(sd_pipeline);

audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt);
/* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */
audio_event_iface_destroy(evt);
audio_pipeline_deinit(sd_pipeline);
vTaskDelete(NULL);

} //** static void play_from_http(void) { is_playing_http = true;

ESP_LOGI(TAG, "[2.0] Create audio pipeline for playback");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();

audio_pipeline_handle_t http_pipeline = audio_pipeline_init(&pipeline_cfg); mem_assert(http_pipeline);

ESP_LOGI(TAG, "[2.1] Create http stream to read data");
http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();
http_cfg.multi_out_num = 1;
http_cfg.out_rb_size = 1024 * 1024;
http_stream_reader = http_stream_init(&http_cfg);

ESP_LOGI(TAG, "[2.2] Create i2s stream to write data to codec chip");
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_cfg.type = AUDIO_STREAM_WRITER;
i2s_stream_writer = i2s_stream_init(&i2s_cfg);

ESP_LOGI(TAG, "[2.3] Create mp3 decoder to decode mp3 file");
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
mp3_decoder = mp3_decoder_init(&mp3_cfg);

ESP_LOGI(TAG, "[2.4] Register all elements to audio pipeline");
audio_pipeline_register(http_pipeline, http_stream_reader, "http");
audio_pipeline_register(http_pipeline, mp3_decoder,        "mp3");
audio_pipeline_register(http_pipeline, i2s_stream_writer,  "i2s");

ESP_LOGI(TAG, "[2.5] Link elements together http_stream-->mp3_decoder-->i2s_stream-->[codec_chip]");
const char *link_tag[5] = {"http", "mp3", "i2s","wav", "file"};
audio_pipeline_link(http_pipeline, &link_tag[0],5 );
ESP_LOGI(TAG, "[2.6] Set up  uri (http as http_stream, mp3 as mp3 decoder, and default output is i2s)");
audio_element_set_uri(http_stream_reader, "https://dl.espressif.com/dl/audio/ff-16b-2c-44100hz.mp3");

ESP_LOGI(TAG, "[3.0] Create fatfs stream to save file");
fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
fatfs_cfg.type = AUDIO_STREAM_WRITER;
audio_element_handle_t fatfs_stream_writer = fatfs_stream_init(&fatfs_cfg);

ESP_LOGI(TAG, "[3.1] Create raw stream to read data");
i2s_stream_reader = i2s_stream_init(&i2s_cfg);
wav_encoder_cfg_t wav_cfg = DEFAULT_WAV_ENCODER_CONFIG();
wav_encoder = wav_encoder_init(&wav_cfg);

ESP_LOGI(TAG, "[3.2] Create pipeline to save audio file");
audio_pipeline_cfg_t pipeline_save_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
audio_pipeline_handle_t pipeline_save = audio_pipeline_init(&pipeline_save_cfg);

ESP_LOGI(TAG, "[3.4] Register all elements to pipeline_save");
audio_pipeline_register(pipeline_save, wav_encoder, "wav");
audio_pipeline_register(pipeline_save, fatfs_stream_writer, "file");

ESP_LOGI(TAG, "[3.5] Link elements together raw_stream-->fatfs_stream");
//const char *link_tag[3] = {"wav", "file",};
//audio_pipeline_link(pipeline, &link_tag[0], 3);

ESP_LOGI(TAG, "[3.6] Connect input ringbuffer of pipeline_save to http stream multi output");
ringbuf_handle_t rb = audio_element_get_output_ringbuf(wav_encoder);
audio_element_set_multi_output_ringbuf(http_stream_reader, rb, 0);

ESP_LOGI(TAG, "[3.6] Set music info to fatfs");
audio_element_info_t music_info = {0};
audio_element_getinfo(i2s_stream_reader, &music_info);
ESP_LOGI(TAG, "[ * ] Save the recording info to the fatfs stream writer, sample_rates=%d, bits=%d, ch=%d",
            music_info.sample_rates, music_info.bits, music_info.channels);
audio_element_setinfo(fatfs_stream_writer, &music_info);

audio_element_set_uri(fatfs_stream_writer, "/sdcard/http.wav");

ESP_LOGI(TAG, "[ 5 ] Set up  event listener");
audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);

ESP_LOGI(TAG, "[5.1] Listening event from all elements of audio pipeline");
audio_pipeline_set_listener(http_pipeline, evt);
audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);

ESP_LOGI(TAG, "[ 6 ] Start pipelines");
audio_pipeline_run(http_pipeline);
audio_pipeline_run(pipeline_save);

while (1) {
    audio_event_iface_msg_t msg;
    esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
        continue;
    }

    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT
        && msg.source == (void *) mp3_decoder
        && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
        audio_element_info_t music_info = {0};
        audio_element_getinfo(mp3_decoder, &music_info);

        ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
                 music_info.sample_rates, music_info.bits, music_info.channels);

        i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels);
        continue;
    }

    /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */
    if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer
        && msg.cmd == AEL_MSG_CMD_REPORT_STATUS
        && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) {
        ESP_LOGW(TAG, "[ * ] Stop event received");
        break;
    }
    /*play pause button*/

     if (((int)msg.data == get_input_play_id()) && (msg.cmd == PERIPH_ADC_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)) {
        toogle_switch = !toogle_switch;
        audio_pipeline_pause(http_pipeline);
        ESP_LOGE(TAG,  "");
        if (toogle_switch) {
           audio_pipeline_pause(http_pipeline);
        } else {
            audio_pipeline_resume(http_pipeline);
        }
        audio_pipeline_run(http_pipeline);
        ESP_LOGE(TAG, "[ 4.1 ] Start playback new pipeline");
    }
}

is_playing_http = false;

ESP_LOGI(TAG, "[5.0] Finished");
audio_pipeline_stop(http_pipeline);
audio_pipeline_wait_for_stop(http_pipeline);
audio_pipeline_terminate(http_pipeline);
audio_pipeline_unregister_more(http_pipeline, http_stream_reader,  mp3_decoder ,i2s_stream_writer,NULL );
audio_pipeline_unregister_more(pipeline_save,wav_encoder, fatfs_stream_writer,NULL);
audio_pipeline_remove_listener(http_pipeline);
audio_event_iface_destroy(evt);
audio_pipeline_deinit(http_pipeline);
}

//** void wait_for_mode_selection() { ESP_LOGI(TAG, "Waiting for mode selection for %d seconds...", MODE_SELECTION_TIMEOUT_SECONDS); vTaskDelay(MODE_SELECTION_TIMEOUT_SECONDS * 1000 / portTICK_PERIOD_MS);

// If no mode is selected, put the device to sleep
if (!is_recording && !is_playing_sd && !is_playing_http) {
    ESP_LOGI(TAG, "No mode selected, entering sleep mode for %d seconds...", SLEEP_TIMEOUT_SECONDS);

    // You can replace the sleep mode depending on your device's sleep capabilities
    esp_sleep_enable_timer_wakeup(SLEEP_TIMEOUT_SECONDS * 1000000);
    esp_deep_sleep_start();
}

} `