From d8fc77101dcf80a3643a00b3446dca1e390ce997 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 10 Aug 2023 15:33:00 +1000 Subject: Give codecs complete control of their input files --- src/audio/fatfs_source.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/audio/fatfs_source.cpp (limited to 'src/audio/fatfs_source.cpp') diff --git a/src/audio/fatfs_source.cpp b/src/audio/fatfs_source.cpp new file mode 100644 index 00000000..6a9aea47 --- /dev/null +++ b/src/audio/fatfs_source.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "fatfs_source.hpp" +#include + +#include +#include +#include + +#include "esp_log.h" +#include "ff.h" + +#include "audio_source.hpp" +#include "codec.hpp" +#include "types.hpp" + +namespace audio { + +static constexpr char kTag[] = "fatfs_src"; + +FatfsSource::FatfsSource(codecs::StreamType t, std::unique_ptr file) + : IStream(t), file_(std::move(file)) {} + +FatfsSource::~FatfsSource() { + f_close(file_.get()); +} + +auto FatfsSource::Read(cpp::span dest) -> ssize_t { + if (f_eof(file_.get())) { + ESP_LOGI(kTag, "read from empty file"); + return 0; + } + UINT bytes_read = 0; + FRESULT res = f_read(file_.get(), dest.data(), dest.size(), &bytes_read); + if (res != FR_OK) { + ESP_LOGE(kTag, "error reading from file"); + return -1; + } + ESP_LOGI(kTag, "read %u bytes into %p (%u)", bytes_read, dest.data(), + dest.size_bytes()); + return bytes_read; +} + +auto FatfsSource::CanSeek() -> bool { + return true; +} + +auto FatfsSource::SeekTo(int64_t destination, SeekFrom from) -> void { + ESP_LOGI(kTag, "seeking to %llu", destination); + switch (from) { + case SeekFrom::kStartOfStream: + f_lseek(file_.get(), destination); + break; + case SeekFrom::kEndOfStream: + f_lseek(file_.get(), f_size(file_.get()) + destination); + break; + case SeekFrom::kCurrentPosition: + f_lseek(file_.get(), f_tell(file_.get()) + destination); + break; + } +} + +auto FatfsSource::CurrentPosition() -> int64_t { + return f_tell(file_.get()); +} +} // namespace audio -- cgit v1.2.3