summaryrefslogtreecommitdiff
path: root/src/audio/fatfs_audio_input.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-04-26 08:49:02 +1000
committerjacqueline <me@jacqueline.id.au>2023-04-26 08:49:02 +1000
commit7972bd4567a99179338259e9e6ce19168c2c0db3 (patch)
treef46642afd36011d3d064e022232e77744b82c6ae /src/audio/fatfs_audio_input.cpp
parent4887f3789817f87bf1272af0b52684e3364270c2 (diff)
parent5575378c1c8171cd716b79d3ab89df1e56ceb9d3 (diff)
downloadtangara-fw-7972bd4567a99179338259e9e6ce19168c2c0db3.tar.gz
Merge branch 'main' into leveldb
Diffstat (limited to 'src/audio/fatfs_audio_input.cpp')
-rw-r--r--src/audio/fatfs_audio_input.cpp94
1 files changed, 31 insertions, 63 deletions
diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp
index 5354c5fd..22d707d6 100644
--- a/src/audio/fatfs_audio_input.cpp
+++ b/src/audio/fatfs_audio_input.cpp
@@ -4,9 +4,12 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <variant>
#include "arena.hpp"
#include "esp_heap_caps.h"
+#include "esp_log.h"
+#include "ff.h"
#include "freertos/portmacro.h"
#include "audio_element.hpp"
@@ -15,43 +18,23 @@
#include "stream_event.hpp"
#include "stream_info.hpp"
#include "stream_message.hpp"
+#include "types.hpp"
static const char* kTag = "SRC";
namespace audio {
-static const std::size_t kChunkSize = 24 * 1024;
-static const std::size_t kChunkReadahead = 2;
-
-FatfsAudioInput::FatfsAudioInput(std::shared_ptr<drivers::SdStorage> storage)
- : IAudioElement(),
- arena_(kChunkSize, kChunkReadahead, MALLOC_CAP_SPIRAM),
- storage_(storage),
- current_file_(),
- is_file_open_(false) {}
+FatfsAudioInput::FatfsAudioInput()
+ : IAudioElement(), current_file_(), is_file_open_(false) {}
FatfsAudioInput::~FatfsAudioInput() {}
-auto FatfsAudioInput::HasUnprocessedInput() -> bool {
- return is_file_open_;
-}
-
-auto FatfsAudioInput::IsOverBuffered() -> bool {
- return arena_.BlocksFree() == 0;
-}
-
-auto FatfsAudioInput::ProcessStreamInfo(const StreamInfo& info) -> void {
+auto FatfsAudioInput::OpenFile(const std::string& path) -> void {
if (is_file_open_) {
f_close(&current_file_);
is_file_open_ = false;
}
-
- if (!info.path) {
- // TODO(jacqueline): Handle errors.
- return;
- }
- ESP_LOGI(kTag, "opening file %s", info.path->c_str());
- std::string path = *info.path;
+ ESP_LOGI(kTag, "opening file %s", path.c_str());
FRESULT res = f_open(&current_file_, path.c_str(), FA_READ);
if (res != FR_OK) {
ESP_LOGE(kTag, "failed to open file! res: %i", res);
@@ -60,51 +43,36 @@ auto FatfsAudioInput::ProcessStreamInfo(const StreamInfo& info) -> void {
}
is_file_open_ = true;
-
- StreamInfo new_info(info);
- new_info.chunk_size = kChunkSize;
- ESP_LOGI(kTag, "chunk size: %u bytes", kChunkSize);
-
- auto event = StreamEvent::CreateStreamInfo(input_events_, new_info);
- SendOrBufferEvent(std::unique_ptr<StreamEvent>(event));
}
-auto FatfsAudioInput::ProcessChunk(const cpp::span<std::byte>& chunk) -> void {}
-
-auto FatfsAudioInput::ProcessEndOfStream() -> void {
- if (is_file_open_) {
- f_close(&current_file_);
- is_file_open_ = false;
- SendOrBufferEvent(std::unique_ptr<StreamEvent>(
- StreamEvent::CreateEndOfStream(input_events_)));
+auto FatfsAudioInput::Process(const std::vector<InputStream>& inputs,
+ OutputStream* output) -> void {
+ if (!is_file_open_) {
+ // TODO(jacqueline): should we clear the stream format?
+ // output->prepare({});
+ return;
}
-}
-auto FatfsAudioInput::Process() -> void {
- if (is_file_open_) {
- auto dest_block = memory::ArenaRef::Acquire(&arena_);
- if (!dest_block) {
- return;
- }
-
- FRESULT result = f_read(&current_file_, dest_block->ptr.start,
- dest_block->ptr.size, &dest_block->ptr.used_size);
- if (result != FR_OK) {
- ESP_LOGE(kTag, "file I/O error %d", result);
- // TODO(jacqueline): Handle errors.
- return;
- }
+ StreamInfo::Format format = StreamInfo::Encoded{codecs::STREAM_MP3};
+ if (!output->prepare(format)) {
+ return;
+ }
- if (dest_block->ptr.used_size < dest_block->ptr.size ||
- f_eof(&current_file_)) {
- f_close(&current_file_);
- is_file_open_ = false;
- }
+ std::size_t max_size = output->data().size_bytes();
+ std::size_t size = 0;
+ FRESULT result =
+ f_read(&current_file_, output->data().data(), max_size, &size);
+ if (result != FR_OK) {
+ ESP_LOGE(kTag, "file I/O error %d", result);
+ // TODO(jacqueline): Handle errors.
+ return;
+ }
- auto dest_event = std::unique_ptr<StreamEvent>(
- StreamEvent::CreateArenaChunk(input_events_, dest_block->Release()));
+ output->add(size);
- SendOrBufferEvent(std::move(dest_event));
+ if (size < max_size || f_eof(&current_file_)) {
+ f_close(&current_file_);
+ is_file_open_ = false;
}
}