diff --git a/main/gay-ipod-fw.cpp b/main/gay-ipod-fw.cpp index 1c232f20..69c0f87f 100644 --- a/main/gay-ipod-fw.cpp +++ b/main/gay-ipod-fw.cpp @@ -17,6 +17,7 @@ #include "driver/sdspi_host.h" #include "driver/spi_common.h" #include "driver/spi_master.h" +#include "esp_heap_trace.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "hal/gpio_types.h" @@ -89,6 +90,7 @@ extern "C" void app_main(void) { ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED)); init_i2c(); init_spi(); + ESP_ERROR_CHECK(gay_ipod::init_adc()); ESP_LOGI(TAG, "Init GPIOs"); gay_ipod::GpioExpander expander; @@ -96,9 +98,6 @@ extern "C" void app_main(void) { // for debugging usb ic // expander.set_sd_mux(gay_ipod::GpioExpander::USB); - ESP_LOGI(TAG, "Init ADC"); - ESP_ERROR_CHECK(gay_ipod::init_adc()); - ESP_LOGI(TAG, "Init SD card"); auto storage_res = gay_ipod::SdStorage::create(&expander); if (storage_res.has_error()) { @@ -130,7 +129,7 @@ extern "C" void app_main(void) { playback->Play("/sdcard/test.mp3"); playback->set_volume(100); - playback->WaitForSongEnd(); + playback->ProcessEvents(); ESP_LOGI(TAG, "Time to deinit."); diff --git a/main/playback.cpp b/main/playback.cpp index 29fa5829..401dc9a3 100644 --- a/main/playback.cpp +++ b/main/playback.cpp @@ -9,6 +9,7 @@ #include "audio_pipeline.h" #include "driver/i2s.h" #include "esp_err.h" +#include "freertos/portmacro.h" #include "mp3_decoder.h" static const char* kTag = "PLAYBACK"; @@ -16,28 +17,13 @@ static const i2s_port_t kI2SPort = I2S_NUM_0; namespace gay_ipod { -// Static functions for interrop with the ESP IDF API, which requires a -// function pointer. -namespace callback { -static DacAudioPlayback* instance = nullptr; - -// Fits the required function pointer signature, but just delegates to the -// wrapper function. Does that make this the wrapper? Who knows. -__attribute__((unused)) // (gcc incorrectly thinks this is unused) -static esp_err_t -on_event(audio_event_iface_msg_t* event, void* data) { - if (instance == nullptr) { - ESP_LOGW(kTag, "uncaught ADF event, type %x", event->cmd); - return ESP_OK; - } - return instance->HandleEvent(event, data); +static audio_element_status_t status_from_the_void(void *status) { + uintptr_t as_pointer_int = reinterpret_cast(status); + return static_cast(as_pointer_int); } -} // namespace callback auto DacAudioPlayback::create(AudioDac* dac) -> cpp::result, Error> { - assert(callback::instance == nullptr); - // Ensure we're soft-muted before initialising, in order to reduce protential // clicks and pops. dac->WriteVolume(255); @@ -119,9 +105,12 @@ auto DacAudioPlayback::create(AudioDac* dac) assert(mp3_decoder != NULL); audio_event_iface_cfg_t event_config = AUDIO_EVENT_IFACE_DEFAULT_CFG(); - event_config.on_cmd = &callback::on_event; event_interface = audio_event_iface_init(&event_config); + audio_pipeline_set_listener(pipeline, event_interface); + audio_element_msg_set_listener(fatfs_stream_reader, event_interface); + audio_element_msg_set_listener(mp3_decoder, event_interface); + audio_element_msg_set_listener(i2s_stream_writer, event_interface); // TODO: most of this is likely post-init, since it involves a decoder. // All the elements of our pipeline have been initialised. Now switch them @@ -149,15 +138,15 @@ DacAudioPlayback::DacAudioPlayback(AudioDac* dac, fatfs_stream_reader_(fatfs_stream_reader), i2s_stream_writer_(i2s_stream_writer), event_interface_(event_interface), - mp3_decoder_(mp3_decoder) { - callback::instance = this; -} + mp3_decoder_(mp3_decoder) {} DacAudioPlayback::~DacAudioPlayback() { dac_->WriteVolume(255); audio_pipeline_remove_listener(pipeline_); - callback::instance = nullptr; + audio_element_msg_remove_listener(fatfs_stream_reader_, event_interface_); + audio_element_msg_remove_listener(mp3_decoder_, event_interface_); + audio_element_msg_remove_listener(i2s_stream_writer_, event_interface_); audio_pipeline_stop(pipeline_); audio_pipeline_wait_for_stop(pipeline_); @@ -190,14 +179,49 @@ void DacAudioPlayback::Pause() { // TODO. } -void DacAudioPlayback::WaitForSongEnd() { +void DacAudioPlayback::ProcessEvents() { while (1) { - audio_element_state_t state = audio_element_get_state(i2s_stream_writer_); - if (state == AEL_STATE_FINISHED) { - return; + audio_event_iface_msg_t event; + esp_err_t err = audio_event_iface_listen(event_interface_, &event, portMAX_DELAY); + if (err != ESP_OK) { + ESP_LOGI(kTag, "error listening for event:%x", err); + continue; + } + ESP_LOGI(kTag, "received event, cmd %i", event.cmd); + + if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT + && event.source == (void *) mp3_decoder_ + && event.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { + audio_element_info_t music_info = {0}; + audio_element_getinfo(mp3_decoder_, &music_info); + ESP_LOGI(kTag, "sample_rate=%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); + } + + if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT + && event.source == (void *) fatfs_stream_reader_ + && event.cmd == AEL_MSG_CMD_REPORT_STATUS) { + audio_element_status_t status = status_from_the_void(event.data); + if (status == AEL_STATUS_STATE_FINISHED) { + // TODO: enqueue next track? + } + } + + if (event.source_type == AUDIO_ELEMENT_TYPE_ELEMENT + && event.source == (void *) i2s_stream_writer_ + && event.cmd == AEL_MSG_CMD_REPORT_STATUS) { + audio_element_status_t status = status_from_the_void(event.data); + if (status == AEL_STATUS_STATE_FINISHED) { + // TODO. + return; + } } - vTaskDelay(pdMS_TO_TICKS(1000)); + if (event.need_free_data) { + ESP_LOGI(kTag, "freeing event data"); + free(event.data); + } } } @@ -216,10 +240,4 @@ auto DacAudioPlayback::volume() -> uint8_t { return volume_; } -auto DacAudioPlayback::HandleEvent(audio_event_iface_msg_t* event, void* data) - -> esp_err_t { - ESP_LOGI(kTag, "got event!"); - return ESP_OK; -} - } // namespace gay_ipod diff --git a/main/playback.hpp b/main/playback.hpp index 88eca5ae..88336105 100644 --- a/main/playback.hpp +++ b/main/playback.hpp @@ -37,8 +37,7 @@ class DacAudioPlayback { void Resume(); void Pause(); - // For debug :) - void WaitForSongEnd(); + void ProcessEvents(); /* for gapless */ void set_next_file(const std::string& filename); @@ -46,8 +45,6 @@ class DacAudioPlayback { void set_volume(uint8_t volume); auto volume() -> uint8_t; - auto HandleEvent(audio_event_iface_msg_t* event, void* data) -> esp_err_t; - // Not copyable or movable. DacAudioPlayback(const DacAudioPlayback&) = delete; DacAudioPlayback& operator=(const DacAudioPlayback&) = delete; diff --git a/sdkconfig b/sdkconfig index 5f4c8ecd..ce84fa01 100644 --- a/sdkconfig +++ b/sdkconfig @@ -70,6 +70,7 @@ CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # # Security features # +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set # CONFIG_SECURE_BOOT is not set # CONFIG_SECURE_FLASH_ENC_ENABLED is not set @@ -167,18 +168,9 @@ CONFIG_REC_ENG_ENABLE_VAD_WWE_AMR=y # # ESP Speech Recognition # -CONFIG_USE_AFE=y -CONFIG_AFE_INTERFACE_V1=y -CONFIG_USE_WAKENET=y -CONFIG_SR_WN_WN5_HILEXIN=y -# CONFIG_SR_WN_WN5X3_HILEXIN is not set -# CONFIG_SR_WN_WN5_NIHAOXIAOZHI is not set -# CONFIG_SR_WN_WN5X3_NIHAOXIAOZHI is not set -# CONFIG_SR_WN_WN5X3_NIHAOXIAOXIN is not set -CONFIG_USE_MULTINET=y -CONFIG_SR_MN_CN_NONE=y -# CONFIG_SR_MN_CN_MULTINET2_SINGLE_RECOGNITION is not set -CONFIG_SR_MN_EN_NONE=y +# CONFIG_USE_AFE is not set +# CONFIG_USE_WAKENET is not set +# CONFIG_USE_MULTINET is not set # end of ESP Speech Recognition # @@ -333,17 +325,73 @@ CONFIG_ESP_TLS_USING_MBEDTLS=y # # ESP32-specific # -CONFIG_ESP32_REV_MIN_0=y +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +# CONFIG_ESP32_REV_MIN_0 is not set # CONFIG_ESP32_REV_MIN_1 is not set # CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_DPORT_WORKAROUND=y +CONFIG_ESP32_REV_MIN_3=y +CONFIG_ESP32_REV_MIN=3 # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 -# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_ESP32_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=-1 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_USE_MEMMAP is not set +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y + +# +# SPIRAM cache workaround debugging +# +# end of SPIRAM cache workaround debugging + +CONFIG_SPIRAM_BANKSWITCH_ENABLE=y +CONFIG_SPIRAM_BANKSWITCH_RESERVE=8 +# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set + +# +# PSRAM clock and cs IO for ESP32-DOWD +# +CONFIG_D0WD_PSRAM_CLK_IO=17 +CONFIG_D0WD_PSRAM_CS_IO=16 +# end of PSRAM clock and cs IO for ESP32-DOWD + +# +# PSRAM clock and cs IO for ESP32-D2WD +# +CONFIG_D2WD_PSRAM_CLK_IO=9 +CONFIG_D2WD_PSRAM_CS_IO=10 +# end of PSRAM clock and cs IO for ESP32-D2WD + +# +# PSRAM clock and cs IO for ESP32-PICO +# +CONFIG_PICO_PSRAM_CS_IO=10 +# end of PSRAM clock and cs IO for ESP32-PICO + +# CONFIG_SPIRAM_CUSTOM_SPIWP_SD3_PIN is not set +CONFIG_SPIRAM_SPIWP_SD3_PIN=7 +# CONFIG_SPIRAM_2T_MODE is not set +# end of SPI RAM config + # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 # CONFIG_ESP32_ULP_COPROC_ENABLED is not set @@ -393,6 +441,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # Common ESP-related # CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y # end of Common ESP-related # @@ -477,9 +526,9 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 # # Sleep Config # -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y # CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set # end of Sleep Config @@ -603,15 +652,16 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 +CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=6 +# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -661,12 +711,17 @@ CONFIG_FATFS_CODEPAGE_437=y # CONFIG_FATFS_CODEPAGE_949 is not set # CONFIG_FATFS_CODEPAGE_950 is not set CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y # CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_API_ENCODING_ANSI_OEM=y +# CONFIG_FATFS_API_ENCODING_UTF_16 is not set +# CONFIG_FATFS_API_ENCODING_UTF_8 is not set CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set # end of FAT Filesystem support @@ -870,6 +925,7 @@ CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +# CONFIG_LWIP_WND_SCALE is not set CONFIG_LWIP_TCP_RTO_TIME=1500 # end of TCP @@ -946,6 +1002,7 @@ CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y # mbedTLS # CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set # CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y @@ -1338,7 +1395,8 @@ CONFIG_STACK_CHECK_NONE=y CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_SPIRAM_SUPPORT is not set +CONFIG_SPIRAM_SUPPORT=y +CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_TRACEMEM_RESERVE_DRAM=0x0 # CONFIG_ULP_COPROC_ENABLED is not set CONFIG_ULP_COPROC_RESERVE_MEM=0 @@ -1365,7 +1423,6 @@ CONFIG_POST_EVENTS_FROM_IRAM_ISR=y # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# CONFIG_ESP_SYSTEM_PD_FLASH is not set # CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_IPC_TASK_STACK_SIZE=1536 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y