diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-05-07 14:19:19 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-05-07 14:19:19 +1000 |
| commit | b242ba998699208c87dc066158964de0866b61e2 (patch) | |
| tree | b0598526a28d6224e2290c35de5923d4234b89eb /src/tangara/audio/fatfs_stream_factory.cpp | |
| parent | 344a46d0664eb75d232eacea91a4957a25e071f6 (diff) | |
| download | tangara-fw-b242ba998699208c87dc066158964de0866b61e2.tar.gz | |
Improve decoder's interface to accept streams
Diffstat (limited to 'src/tangara/audio/fatfs_stream_factory.cpp')
| -rw-r--r-- | src/tangara/audio/fatfs_stream_factory.cpp | 104 |
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 |
