FlacLoader.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include "Buffer.h"
  8. #include "FlacTypes.h"
  9. #include "Loader.h"
  10. #include <AK/BitStream.h>
  11. #include <AK/Stream.h>
  12. #include <AK/Types.h>
  13. #include <AK/Variant.h>
  14. #include <LibCore/FileStream.h>
  15. namespace Audio {
  16. class FlacInputStream : public Variant<Core::InputFileStream, InputMemoryStream> {
  17. public:
  18. using Variant<Core::InputFileStream, InputMemoryStream>::Variant;
  19. void seek(size_t pos)
  20. {
  21. this->visit(
  22. [&](auto& stream) {
  23. stream.seek(pos);
  24. });
  25. }
  26. InputBitStream bit_stream()
  27. {
  28. return this->visit(
  29. [&](auto& stream) {
  30. return InputBitStream(stream);
  31. });
  32. }
  33. };
  34. ALWAYS_INLINE u8 frame_channel_type_to_channel_count(FlacFrameChannelType channel_type);
  35. // Sign-extend an arbitrary-size signed number to 64 bit signed
  36. ALWAYS_INLINE i64 sign_extend(u32 n, u8 size);
  37. // Decodes the sign representation method used in Rice coding.
  38. // Numbers alternate between positive and negative: 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, ...
  39. ALWAYS_INLINE i32 rice_to_signed(u32 x);
  40. // decoders
  41. // read a UTF-8 encoded number, even if it is not a valid codepoint
  42. ALWAYS_INLINE u64 read_utf8_char(InputStream& input);
  43. // decode a single number encoded with exponential golomb encoding of the specified order
  44. ALWAYS_INLINE i32 decode_unsigned_exp_golomb(u8 order, InputBitStream& bit_input);
  45. class FlacLoaderPlugin : public LoaderPlugin {
  46. public:
  47. FlacLoaderPlugin(const StringView& path);
  48. FlacLoaderPlugin(const ByteBuffer& buffer);
  49. virtual bool sniff() override;
  50. virtual bool has_error() override { return !m_error_string.is_null(); }
  51. virtual const String& error_string() override { return m_error_string; }
  52. virtual RefPtr<Buffer> get_more_samples(size_t max_bytes_to_read_from_input = 128 * KiB) override;
  53. virtual void reset() override;
  54. virtual void seek(const int position) override;
  55. // FIXME
  56. virtual int loaded_samples() override { return 0; }
  57. virtual int total_samples() override { return m_total_samples; }
  58. virtual u32 sample_rate() override { return m_sample_rate; }
  59. virtual u16 num_channels() override { return m_num_channels; }
  60. virtual PcmSampleFormat pcm_format() override { return m_sample_format; }
  61. virtual RefPtr<Core::File> file() override { return m_file; }
  62. bool is_fixed_blocksize_stream() const { return m_min_block_size == m_max_block_size; }
  63. bool sample_count_unknown() const { return m_total_samples == 0; }
  64. private:
  65. bool parse_header();
  66. // Either returns the metadata block or sets error message.
  67. // Additionally, increments m_data_start_location past the read meta block.
  68. FlacRawMetadataBlock next_meta_block(InputBitStream& bit_input);
  69. // Fetches and sets the next FLAC frame
  70. void next_frame();
  71. // Helper of next_frame that fetches a sub frame's header
  72. FlacSubframeHeader next_subframe_header(InputBitStream& bit_input, u8 channel_index);
  73. // Helper of next_frame that decompresses a subframe
  74. Vector<i32> parse_subframe(FlacSubframeHeader& subframe_header, InputBitStream& bit_input);
  75. // Subframe-internal data decoders (heavy lifting)
  76. Vector<i32> decode_fixed_lpc(FlacSubframeHeader& subframe, InputBitStream& bit_input);
  77. Vector<i32> decode_verbatim(FlacSubframeHeader& subframe, InputBitStream& bit_input);
  78. Vector<i32> decode_custom_lpc(FlacSubframeHeader& subframe, InputBitStream& bit_input);
  79. Vector<i32> decode_residual(Vector<i32>& decoded, FlacSubframeHeader& subframe, InputBitStream& bit_input);
  80. // decode a single rice partition that has its own rice parameter
  81. ALWAYS_INLINE Vector<i32> decode_rice_partition(u8 partition_type, u32 partitions, u32 partition_index, FlacSubframeHeader& subframe, InputBitStream& bit_input);
  82. // Converters for special coding used in frame headers
  83. ALWAYS_INLINE u32 convert_sample_count_code(u8 sample_count_code);
  84. ALWAYS_INLINE u32 convert_sample_rate_code(u8 sample_rate_code);
  85. ALWAYS_INLINE PcmSampleFormat convert_bit_depth_code(u8 bit_depth_code);
  86. bool m_valid { false };
  87. RefPtr<Core::File> m_file;
  88. String m_error_string;
  89. OwnPtr<ResampleHelper<double>> m_resampler;
  90. // Data obtained directly from the FLAC metadata: many values have specific bit counts
  91. u32 m_sample_rate { 0 }; // 20 bit
  92. u8 m_num_channels { 0 }; // 3 bit
  93. PcmSampleFormat m_sample_format; // 5 bits for the integer bit depth
  94. // Blocks are units of decoded audio data
  95. u16 m_min_block_size { 0 };
  96. u16 m_max_block_size { 0 };
  97. // Frames are units of encoded audio data, both of these are 24-bit
  98. u32 m_min_frame_size { 0 }; //24 bit
  99. u32 m_max_frame_size { 0 }; // 24 bit
  100. u64 m_total_samples { 0 }; // 36 bit
  101. u8 m_md5_checksum[128 / 8]; // 128 bit (!)
  102. // keep track of the start of the data in the FLAC stream to seek back more easily
  103. u64 m_data_start_location { 0 };
  104. OwnPtr<FlacInputStream> m_stream;
  105. Optional<FlacFrameHeader> m_current_frame;
  106. Vector<Frame> m_current_frame_data;
  107. u64 m_current_sample_or_frame { 0 };
  108. };
  109. }