[audio] Support reallocating non-empty AudioTransferBuffer (#13979)

This commit is contained in:
Kevin Ahrendt
2026-02-15 15:09:35 -06:00
committed by GitHub
parent 15da6d0a0b
commit 066419019f
2 changed files with 31 additions and 6 deletions

View File

@@ -2,6 +2,8 @@
#ifdef USE_ESP32
#include <cstring>
#include "esphome/core/helpers.h"
namespace esphome {
@@ -75,12 +77,32 @@ bool AudioTransferBuffer::has_buffered_data() const {
}
bool AudioTransferBuffer::reallocate(size_t new_buffer_size) {
if (this->buffer_length_ > 0) {
// Buffer currently has data, so reallocation is impossible
if (this->buffer_ == nullptr) {
return this->allocate_buffer_(new_buffer_size);
}
if (new_buffer_size < this->buffer_length_) {
// New size is too small to hold existing data
return false;
}
this->deallocate_buffer_();
return this->allocate_buffer_(new_buffer_size);
// Shift existing data to the start of the buffer so realloc preserves it
if ((this->buffer_length_ > 0) && (this->data_start_ != this->buffer_)) {
std::memmove(this->buffer_, this->data_start_, this->buffer_length_);
this->data_start_ = this->buffer_;
}
RAMAllocator<uint8_t> allocator;
uint8_t *new_buffer = allocator.reallocate(this->buffer_, new_buffer_size);
if (new_buffer == nullptr) {
// Reallocation failed, but the original buffer is still valid
return false;
}
this->buffer_ = new_buffer;
this->data_start_ = this->buffer_;
this->buffer_size_ = new_buffer_size;
return true;
}
bool AudioTransferBuffer::allocate_buffer_(size_t buffer_size) {
@@ -115,7 +137,7 @@ size_t AudioSourceTransferBuffer::transfer_data_from_source(TickType_t ticks_to_
if (pre_shift) {
// Shift data in buffer to start
if (this->buffer_length_ > 0) {
memmove(this->buffer_, this->data_start_, this->buffer_length_);
std::memmove(this->buffer_, this->data_start_, this->buffer_length_);
}
this->data_start_ = this->buffer_;
}
@@ -150,7 +172,7 @@ size_t AudioSinkTransferBuffer::transfer_data_to_sink(TickType_t ticks_to_wait,
if (post_shift) {
// Shift unwritten data to the start of the buffer
memmove(this->buffer_, this->data_start_, this->buffer_length_);
std::memmove(this->buffer_, this->data_start_, this->buffer_length_);
this->data_start_ = this->buffer_;
}

View File

@@ -56,6 +56,9 @@ class AudioTransferBuffer {
/// @return True if there is data, false otherwise.
virtual bool has_buffered_data() const;
/// @brief Reallocates the transfer buffer, preserving any existing data.
/// @param new_buffer_size The new size in bytes. Must be at least as large as available().
/// @return True if successful, false otherwise. On failure, the original buffer remains valid.
bool reallocate(size_t new_buffer_size);
protected: