summaryrefslogtreecommitdiff
path: root/src/tangara/audio/fatfs_stream_factory.cpp
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2024-05-10 12:20:51 +1000
committerailurux <ailuruxx@gmail.com>2024-05-10 12:20:51 +1000
commite4ce7c4ac23402e09be8d6a52e0f739c0dff4ff0 (patch)
tree3e04ac08a884fb6d6c887cd70218316a30ae3371 /src/tangara/audio/fatfs_stream_factory.cpp
parent5b109ed32709c271a6803382c5738802919c9c69 (diff)
parent2afeb2989b2f845664e12f93e850aab983be12cc (diff)
downloadtangara-fw-e4ce7c4ac23402e09be8d6a52e0f739c0dff4ff0.tar.gz
Merge branch 'main' of codeberg.org:cool-tech-zone/tangara-fw
Diffstat (limited to 'src/tangara/audio/fatfs_stream_factory.cpp')
-rw-r--r--src/tangara/audio/fatfs_stream_factory.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/tangara/audio/fatfs_stream_factory.cpp b/src/tangara/audio/fatfs_stream_factory.cpp
new file mode 100644
index 00000000..db08e68c
--- /dev/null
+++ b/src/tangara/audio/fatfs_stream_factory.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "audio/fatfs_stream_factory.hpp"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "database/database.hpp"
+#include "esp_log.h"
+#include "ff.h"
+#include "freertos/portmacro.h"
+#include "freertos/projdefs.h"
+
+#include "audio/audio_source.hpp"
+#include "audio/fatfs_source.hpp"
+#include "codec.hpp"
+#include "database/tag_parser.hpp"
+#include "database/track.hpp"
+#include "drivers/spi.hpp"
+#include "system_fsm/service_locator.hpp"
+#include "tasks.hpp"
+#include "types.hpp"
+
+[[maybe_unused]] static const char* kTag = "SRC";
+
+namespace audio {
+
+FatfsStreamFactory::FatfsStreamFactory(system_fsm::ServiceLocator& services)
+ : services_(services) {}
+
+auto FatfsStreamFactory::create(database::TrackId id, uint32_t offset)
+ -> std::shared_ptr<TaggedStream> {
+ auto db = services_.database().lock();
+ if (!db) {
+ return {};
+ }
+ auto path = db->getTrackPath(id);
+ if (!path) {
+ return {};
+ }
+ return create(*path, offset);
+}
+
+auto FatfsStreamFactory::create(std::string path, uint32_t offset)
+ -> std::shared_ptr<TaggedStream> {
+ auto tags = services_.tag_parser().ReadAndParseTags(path);
+ if (!tags) {
+ ESP_LOGE(kTag, "failed to read tags");
+ return {};
+ }
+
+ if (!tags->title()) {
+ tags->title(path);
+ }
+
+ auto stream_type = ContainerToStreamType(tags->encoding());
+ if (!stream_type.has_value()) {
+ ESP_LOGE(kTag, "couldn't match container to stream");
+ return {};
+ }
+
+ std::unique_ptr<FIL> file = std::make_unique<FIL>();
+ FRESULT res;
+
+ {
+ auto lock = drivers::acquire_spi();
+ res = f_open(file.get(), path.c_str(), FA_READ);
+ }
+
+ if (res != FR_OK) {
+ ESP_LOGE(kTag, "failed to open file! res: %i", res);
+ return {};
+ }
+
+ return std::make_shared<TaggedStream>(
+ tags, std::make_unique<FatfsSource>(stream_type.value(), std::move(file)),
+ path, offset);
+}
+
+auto FatfsStreamFactory::ContainerToStreamType(database::Container enc)
+ -> std::optional<codecs::StreamType> {
+ switch (enc) {
+ case database::Container::kMp3:
+ return codecs::StreamType::kMp3;
+ case database::Container::kWav:
+ return codecs::StreamType::kWav;
+ case database::Container::kOgg:
+ return codecs::StreamType::kVorbis;
+ case database::Container::kFlac:
+ return codecs::StreamType::kFlac;
+ case database::Container::kOpus:
+ return codecs::StreamType::kOpus;
+ case database::Container::kUnsupported:
+ default:
+ return {};
+ }
+}
+
+} // namespace audio