Make the drain buffer very large, and move it into PSRAM

the i2s handler and streambuffer metadata are both still in iram for
good performance. otherwise, this seems to be enough to make gapless
playback work.
custom
jacqueline 1 year ago
parent 79be8a8e6e
commit 29a246a733
  1. 1
      sdkconfig.common
  2. 22
      src/audio/audio_fsm.cpp

@ -22,7 +22,6 @@ CONFIG_SPI_MASTER_IN_IRAM=y
# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set # CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set
# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set # CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
CONFIG_I2S_ISR_IRAM_SAFE=y
# CONFIG_ETH_USE_ESP32_EMAC is not set # CONFIG_ETH_USE_ESP32_EMAC is not set
# CONFIG_ETH_USE_SPI_ETHERNET is not set # CONFIG_ETH_USE_SPI_ETHERNET is not set
# CONFIG_ESP_EVENT_POST_FROM_ISR is not set # CONFIG_ESP_EVENT_POST_FROM_ISR is not set

@ -13,7 +13,9 @@
#include "audio_sink.hpp" #include "audio_sink.hpp"
#include "bluetooth_types.hpp" #include "bluetooth_types.hpp"
#include "esp_heap_caps.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h" #include "freertos/portmacro.h"
#include "freertos/projdefs.h" #include "freertos/projdefs.h"
@ -192,20 +194,28 @@ void AudioState::react(const TogglePlayPause& ev) {
namespace states { namespace states {
// Two seconds of samples for two channels, at a representative sample rate.
constexpr size_t kDrainBufferSize = sizeof(sample::Sample) * 48000 * 4;
static StreamBufferHandle_t sDrainBuffer;
void Uninitialised::react(const system_fsm::BootComplete& ev) { void Uninitialised::react(const system_fsm::BootComplete& ev) {
sServices = ev.services; sServices = ev.services;
constexpr size_t kDrainBufferSize =
drivers::kI2SBufferLengthFrames * sizeof(sample::Sample) * 2 * 8;
ESP_LOGI(kTag, "allocating drain buffer, size %u KiB", ESP_LOGI(kTag, "allocating drain buffer, size %u KiB",
kDrainBufferSize / 1024); kDrainBufferSize / 1024);
StreamBufferHandle_t stream = xStreamBufferCreateWithCaps(
kDrainBufferSize, sizeof(sample::Sample), MALLOC_CAP_DMA); auto meta = reinterpret_cast<StaticStreamBuffer_t*>(
heap_caps_malloc(sizeof(StaticStreamBuffer_t), MALLOC_CAP_DMA));
auto storage = reinterpret_cast<uint8_t*>(
heap_caps_malloc(kDrainBufferSize, MALLOC_CAP_SPIRAM));
sDrainBuffer = xStreamBufferCreateStatic(
kDrainBufferSize, sizeof(sample::Sample), storage, meta);
sFileSource.reset( sFileSource.reset(
new FatfsAudioInput(sServices->tag_parser(), sServices->bg_worker())); new FatfsAudioInput(sServices->tag_parser(), sServices->bg_worker()));
sI2SOutput.reset(new I2SAudioOutput(stream, sServices->gpios())); sI2SOutput.reset(new I2SAudioOutput(sDrainBuffer, sServices->gpios()));
sBtOutput.reset(new BluetoothAudioOutput(stream, sServices->bluetooth(), sBtOutput.reset(new BluetoothAudioOutput(sDrainBuffer, sServices->bluetooth(),
sServices->bg_worker())); sServices->bg_worker()));
auto& nvs = sServices->nvs(); auto& nvs = sServices->nvs();

Loading…
Cancel
Save