summaryrefslogtreecommitdiff
path: root/src/codecs/source_buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codecs/source_buffer.cpp')
-rw-r--r--src/codecs/source_buffer.cpp75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/codecs/source_buffer.cpp b/src/codecs/source_buffer.cpp
new file mode 100644
index 00000000..5955523e
--- /dev/null
+++ b/src/codecs/source_buffer.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "source_buffer.hpp"
+#include <sys/_stdint.h>
+
+#include <algorithm>
+#include <cstring>
+
+#include "esp_heap_caps.h"
+#include "esp_log.h"
+
+#include "codec.hpp"
+
+namespace codecs {
+
+static constexpr char kTag[] = "dec_buf";
+static constexpr size_t kBufferSize = 1024 * 8;
+
+SourceBuffer::SourceBuffer()
+ : buffer_(reinterpret_cast<std::byte*>(
+ heap_caps_malloc(kBufferSize, MALLOC_CAP_SPIRAM)),
+ kBufferSize),
+ bytes_in_buffer_(0),
+ offset_of_bytes_(0) {
+ assert(buffer_.data() != nullptr);
+}
+
+SourceBuffer::~SourceBuffer() {
+ free(buffer_.data());
+}
+
+auto SourceBuffer::Refill(IStream* src) -> bool {
+ if (bytes_in_buffer_ == buffer_.size_bytes()) {
+ return false;
+ }
+ bool eof = false;
+ AddBytes([&](cpp::span<std::byte> buf) -> size_t {
+ size_t bytes_read = src->Read(buf);
+ eof = bytes_read == 0;
+ return bytes_read;
+ });
+ return eof;
+}
+
+auto SourceBuffer::AddBytes(std::function<size_t(cpp::span<std::byte>)> writer)
+ -> void {
+ if (offset_of_bytes_ > 0) {
+ std::memmove(buffer_.data(), buffer_.data() + offset_of_bytes_,
+ bytes_in_buffer_);
+ offset_of_bytes_ = 0;
+ }
+ size_t added_bytes = std::invoke(writer, buffer_.subspan(bytes_in_buffer_));
+ assert(bytes_in_buffer_ + added_bytes <= buffer_.size_bytes());
+ bytes_in_buffer_ += added_bytes;
+}
+
+auto SourceBuffer::ConsumeBytes(
+ std::function<size_t(cpp::span<std::byte>)> reader) -> void {
+ size_t bytes_consumed = std::invoke(
+ reader, buffer_.subspan(offset_of_bytes_).first(bytes_in_buffer_));
+ assert(bytes_consumed <= bytes_in_buffer_);
+
+ bytes_in_buffer_ -= bytes_consumed;
+ if (bytes_in_buffer_ == 0) {
+ offset_of_bytes_ = 0;
+ } else {
+ offset_of_bytes_ += bytes_consumed;
+ }
+}
+
+} // namespace codecs