Free the i2s dma channel when it's not in use

It turns out this is why bluetooth playback keeps running out of memory
/facepalm
custom
jacqueline 2 years ago
parent 782e8dc8c2
commit 912f9c0757
  1. 10
      src/audio/audio_fsm.cpp
  2. 16
      src/audio/i2s_audio_output.cpp
  3. 3
      src/audio/include/i2s_audio_output.hpp
  4. 5
      src/drivers/i2s_dac.cpp

@ -98,13 +98,6 @@ namespace states {
void Uninitialised::react(const system_fsm::BootComplete& ev) {
sServices = ev.services;
auto dac = drivers::I2SDac::create(sServices->gpios());
if (!dac) {
events::System().Dispatch(system_fsm::FatalError{});
events::Ui().Dispatch(system_fsm::FatalError{});
return;
}
constexpr size_t kDrainBufferSize =
drivers::kI2SBufferLengthFrames * sizeof(sample::Sample) * 2 * 8;
ESP_LOGI(kTag, "allocating drain buffer, size %u KiB",
@ -113,8 +106,7 @@ void Uninitialised::react(const system_fsm::BootComplete& ev) {
kDrainBufferSize, sizeof(sample::Sample) * 2, MALLOC_CAP_DMA);
sFileSource.reset(new FatfsAudioInput(sServices->tag_parser()));
sI2SOutput.reset(new I2SAudioOutput(stream, sServices->gpios(),
std::unique_ptr<drivers::I2SDac>{*dac}));
sI2SOutput.reset(new I2SAudioOutput(stream, sServices->gpios()));
sBtOutput.reset(new BluetoothAudioOutput(stream, sServices->bluetooth()));
auto& nvs = sServices->nvs();

@ -43,18 +43,15 @@ static constexpr uint16_t kDefaultVolume = 0x100;
static constexpr size_t kDrainBufferSize = 8 * 1024;
I2SAudioOutput::I2SAudioOutput(StreamBufferHandle_t s,
drivers::IGpios& expander,
std::unique_ptr<drivers::I2SDac> dac)
drivers::IGpios& expander)
: IAudioOutput(s),
expander_(expander),
dac_(std::move(dac)),
dac_(),
current_mode_(Modes::kOff),
current_config_(),
left_difference_(0),
current_volume_(0),
max_volume_(0) {
dac_->SetSource(stream());
}
max_volume_(0) {}
I2SAudioOutput::~I2SAudioOutput() {
dac_->Stop();
@ -67,8 +64,15 @@ auto I2SAudioOutput::SetMode(Modes mode) -> void {
}
if (mode == Modes::kOff) {
dac_->Stop();
dac_.reset();
return;
} else if (current_mode_ == Modes::kOff) {
auto instance = drivers::I2SDac::create(expander_);
if (!instance) {
return;
}
dac_.reset(*instance);
dac_->SetSource(stream());
dac_->Start();
}
current_mode_ = mode;

@ -21,8 +21,7 @@ namespace audio {
class I2SAudioOutput : public IAudioOutput {
public:
I2SAudioOutput(StreamBufferHandle_t,
drivers::IGpios& expander,
std::unique_ptr<drivers::I2SDac> dac);
drivers::IGpios& expander);
~I2SAudioOutput();
auto SetMode(Modes) -> void override;

@ -91,15 +91,12 @@ I2SDac::I2SDac(IGpios& gpio, i2s_chan_handle_t i2s_handle)
I2S_SLOT_MODE_STEREO)) {
clock_config_.clk_src = I2S_CLK_SRC_APLL;
// Keep the 5V circuity off until it's needed.
gpio_.WriteSync(IGpios::Pin::kAmplifierEnable, false);
gpio_.WriteSync(IGpios::Pin::kAmplifierEnable, true);
// Reset all registers back to their default values.
wm8523::WriteRegister(wm8523::Register::kReset, 1);
vTaskDelay(pdMS_TO_TICKS(10));
wm8523::WriteRegister(wm8523::Register::kPsCtrl, 0b0);
gpio_.WriteSync(IGpios::Pin::kAmplifierEnable, true);
}
I2SDac::~I2SDac() {

Loading…
Cancel
Save