14 std::unique_ptr<AudioSinkTransferBuffer> sink_buffer = make_unique<AudioSinkTransferBuffer>();
16 if (!sink_buffer->allocate_buffer_(buffer_size)) {
63 return ((this->
ring_buffer_->available() > 0) || (this->available() > 0));
86 if (new_buffer ==
nullptr) {
103 if (this->
buffer_ ==
nullptr) {
114 if (this->
buffer_ !=
nullptr) {
126 size_t bytes_written = 0;
149 return bytes_written;
159 return ((this->
ring_buffer_->available() > 0) || (this->available() > 0));
165#pragma GCC diagnostic push
166#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
167std::unique_ptr<AudioSourceTransferBuffer> AudioSourceTransferBuffer::create(
size_t buffer_size) {
168 std::unique_ptr<AudioSourceTransferBuffer> source_buffer = make_unique<AudioSourceTransferBuffer>();
170 if (!source_buffer->allocate_buffer_(buffer_size)) {
174 return source_buffer;
177size_t AudioSourceTransferBuffer::transfer_data_from_source(TickType_t ticks_to_wait,
bool pre_shift) {
180 if (this->buffer_length_ > 0) {
181 std::memmove(this->buffer_, this->data_start_, this->buffer_length_);
183 this->data_start_ = this->buffer_;
187 size_t bytes_read = 0;
188 if (bytes_to_read > 0) {
189 if (this->ring_buffer_ !=
nullptr) {
190 bytes_read = this->ring_buffer_->read((
void *) this->get_buffer_end(), bytes_to_read, ticks_to_wait);
193 this->increase_buffer_length(bytes_read);
201#pragma GCC diagnostic pop
209 bytes = std::min(bytes, this->
length_);
215 std::shared_ptr<ring_buffer::RingBuffer> ring_buffer,
size_t max_fill_bytes, uint8_t alignment_bytes) {
216 if (ring_buffer ==
nullptr || max_fill_bytes == 0 || alignment_bytes == 0 || alignment_bytes >
MAX_ALIGNMENT_BYTES) {
219 return std::unique_ptr<RingBufferAudioSource>(
282 if (real_bytes == 0 || frame_bytes == 0 || real_bytes % frame_bytes != 0) {
320 size_t chunk_length = 0;
322 if (item ==
nullptr) {
326 uint8_t *chunk_data =
static_cast<uint8_t *
>(item);
327 bool exposing_splice_frame =
false;
332 if (chunk_length < needed) {
340 chunk_data += needed;
341 chunk_length -= needed;
343 exposing_splice_frame =
true;
350 const size_t aligned_bytes = chunk_length - trailing;
356 if (exposing_splice_frame) {
366 if (aligned_bytes == 0) {
375 return aligned_bytes;
An STL allocator that uses SPI or internal RAM.
T * reallocate(T *p, size_t n)
void deallocate(T *p, size_t n)
virtual size_t audio_sink_write(uint8_t *data, size_t length, TickType_t ticks_to_wait)=0
size_t transfer_data_to_sink(TickType_t ticks_to_wait, bool post_shift=true)
Writes any available data in the transfer buffer to the sink.
void clear_buffered_data() override
AudioSinkCallback * sink_callback_
bool has_buffered_data() const override
speaker::Speaker * speaker_
static std::unique_ptr< AudioSinkTransferBuffer > create(size_t buffer_size)
Creates a new sink transfer buffer.
size_t free() const
Returns the transfer buffer's currrently free bytes available to write.
virtual bool has_buffered_data() const
Tests if there is any data in the tranfer buffer or the source/sink.
virtual void clear_buffered_data()
Clears data in the transfer buffer and, if possible, the source/sink.
~AudioTransferBuffer()
Destructor that deallocates the transfer buffer.
void increase_buffer_length(size_t bytes)
Updates the internal state of the transfer buffer.
bool reallocate(size_t new_buffer_size)
Reallocates the transfer buffer, preserving any existing data.
bool allocate_buffer_(size_t buffer_size)
Allocates the transfer buffer in external memory, if available.
void decrease_buffer_length(size_t bytes)
Updates the internal state of the transfer buffer.
size_t available() const
Returns the transfer buffer's currently available bytes to read.
std::shared_ptr< ring_buffer::RingBuffer > ring_buffer_
void deallocate_buffer_()
Deallocates the buffer and resets the class variables.
void set_data(const uint8_t *data, size_t length)
Sets the data pointer and length for the buffer.
const uint8_t * data_start_
const uint8_t * data() const override
void consume(size_t bytes) override
uint8_t item_trailing_length_
uint8_t splice_buffer_[MAX_ALIGNMENT_BYTES]
void release_item_()
Releases the currently held ring buffer item, first copying any trailing sub-frame bytes into the spl...
void consume(size_t bytes) override
~RingBufferAudioSource() override
size_t current_available_
bool has_buffered_data() const override
size_t expose_padded_partial(size_t frame_bytes)
Zero-pads held whole frames short of an alignment unit and exposes them, so a stream's tail is not st...
uint8_t * item_trailing_ptr_
static constexpr size_t MAX_ALIGNMENT_BYTES
Maximum supported alignment. Sized to cover 32-bit samples across up to 2 channels (8 bytes).
static std::unique_ptr< RingBufferAudioSource > create(std::shared_ptr< ring_buffer::RingBuffer > ring_buffer, size_t max_fill_bytes, uint8_t alignment_bytes=1)
Creates a new ring-buffer-backed audio source after validating its parameters.
RingBufferAudioSource(std::shared_ptr< ring_buffer::RingBuffer > ring_buffer, size_t max_fill_bytes, uint8_t alignment_bytes)
Constructs a new ring-buffer-backed audio source.
void clear_buffered_data()
Discards all buffered audio: releases any held ring buffer item, clears the source's in-flight state,...
size_t fill(TickType_t ticks_to_wait) override
An unconsumed exposure stays in place and fill() returns 0 until it is fully consumed.
std::shared_ptr< ring_buffer::RingBuffer > ring_buffer_
virtual size_t play(const uint8_t *data, size_t length)=0
Plays the provided audio data.
virtual bool has_buffered_data() const =0