summaryrefslogtreecommitdiff
path: root/src/codecs/include/alac.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codecs/include/alac.hpp')
-rw-r--r--src/codecs/include/alac.hpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/codecs/include/alac.hpp b/src/codecs/include/alac.hpp
new file mode 100644
index 00000000..a0dcd1f2
--- /dev/null
+++ b/src/codecs/include/alac.hpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2025 ayumi <ayumi@noreply.codeberg.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <variant>
+
+extern "C" {
+ #include "decomp.h"
+}
+#include "sample.hpp"
+
+#include "codec.hpp"
+
+namespace codecs {
+
+class AlacDecoder : public ICodec {
+ public:
+ AlacDecoder();
+ ~AlacDecoder();
+
+ auto OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
+ -> cpp::result<OutputFormat, Error> override;
+ auto DecodeTo(std::span<sample::Sample> destination)
+ -> cpp::result<OutputInfo, Error> override;
+
+ AlacDecoder(const AlacDecoder&) = delete;
+ AlacDecoder& operator=(const AlacDecoder&) = delete;
+
+ private:
+ auto readBoxHeader()
+ -> cpp::result<std::tuple<uint64_t, std::array<std::byte, 4>>, ICodec::Error>;
+ auto readFullBoxHeader() -> std::tuple<uint8_t, uint32_t>;
+ auto readFtyp(uint64_t size) -> cpp::result<void, ICodec::Error>;
+ void readFree(uint64_t size);
+ auto readStsd() -> cpp::result<void, ICodec::Error>;
+ auto readStts() -> cpp::result<void, ICodec::Error>;
+ auto readStsc() -> cpp::result<void, ICodec::Error>;
+ auto readStsz() -> cpp::result<void, ICodec::Error>;
+ auto readStco() -> cpp::result<void, ICodec::Error>;
+ auto readCo64() -> cpp::result<void, ICodec::Error>;
+ auto readBox() -> cpp::result<uint64_t, ICodec::Error>;
+ auto readContainer(uint64_t size) -> cpp::result<uint64_t, ICodec::Error>;
+ auto getFrameDuration(uint32_t frame) -> cpp::result<uint32_t, ICodec::Error>;
+ auto getFrameSize(uint32_t frame) -> uint32_t;
+ auto getTotalSamples() -> uint64_t;
+ auto getTotalFrames() -> uint32_t;
+ auto getTotalFrameSize() -> uint64_t;
+ auto frameToOffset(uint32_t frame)
+ -> cpp::result<std::tuple<uint64_t, uint32_t>, ICodec::Error>;
+ auto getChunkMixMaxFrames(uint32_t chunk)
+ -> cpp::result<std::tuple<uint32_t, uint32_t>, ICodec::Error>;
+ auto sampleToFrame(uint64_t sample)
+ -> cpp::result<std::tuple<uint32_t, uint32_t>, ICodec::Error>;
+ auto UnpackFrame(uint32_t offset) -> cpp::result<void, ICodec::Error>;
+
+ std::shared_ptr<IStream> input_;
+ alac_file alac_;
+ uint8_t bitdepth_;
+ uint8_t channels_;
+ uint16_t sampleRate_;
+ uint16_t index_;
+
+ std::vector<std::tuple<uint32_t, uint32_t>> stts_;
+ std::vector<std::tuple<uint32_t, uint32_t>> stsc_;
+ std::variant<uint32_t, std::vector<uint32_t>> stsz_;
+ std::vector<uint64_t> stco_;
+
+ bool hasStts_ = false;
+ bool hasStsc_ = false;
+ bool hasStsz_ = false;
+ bool hasStco_ = false;
+
+ uint32_t chunk_;
+ uint32_t frame_;
+ std::vector<std::byte> in_;
+ std::vector<std::byte> out_;
+ size_t outSize_;
+ size_t outOff_;
+};
+
+} // namespace codecs