diff --git a/Userland/Libraries/LibAudio/FlacLoader.cpp b/Userland/Libraries/LibAudio/FlacLoader.cpp index 188860a0cc..8d23a8d1a5 100644 --- a/Userland/Libraries/LibAudio/FlacLoader.cpp +++ b/Userland/Libraries/LibAudio/FlacLoader.cpp @@ -384,10 +384,9 @@ LoaderSamples FlacLoaderPlugin::next_frame() dbgln("FLAC Warning: Inserting seek point for sample {} failed: {}", sample_index, maybe_error.release_error()); } - auto checksum_stream = TRY(try_make>(MaybeOwned(*m_stream))); - BigEndianInputBitStream bit_stream { MaybeOwned { *checksum_stream } }; - - // TODO: Check the CRC-16 checksum by keeping track of read data. + auto frame_checksum_stream = TRY(try_make>(MaybeOwned(*m_stream))); + auto header_checksum_stream = TRY(try_make>(MaybeOwned(*frame_checksum_stream))); + BigEndianInputBitStream bit_stream { MaybeOwned { *header_checksum_stream } }; // 11.22. FRAME_HEADER u16 sync_code = TRY(bit_stream.read_bits(14)); @@ -431,14 +430,14 @@ LoaderSamples FlacLoaderPlugin::next_frame() } // It does not matter whether we extract the checksum from the digest here, or extract the digest 0x00 after processing the checksum. - auto const calculated_checksum = checksum_stream->digest(); + auto const calculated_header_checksum = header_checksum_stream->digest(); // 11.22.11. FRAME CRC - u8 specified_checksum = TRY(bit_stream.read_bits(8)); + u8 specified_header_checksum = TRY(bit_stream.read_bits(8)); VERIFY(bit_stream.is_aligned_to_byte_boundary()); - if (specified_checksum != calculated_checksum) - dbgln("FLAC frame {}: Calculated header checksum {:02x} is different from specified checksum {:02x}", m_current_sample_or_frame, calculated_checksum, specified_checksum); + if (specified_header_checksum != calculated_header_checksum) + dbgln("FLAC frame {}: Calculated header checksum {:02x} is different from specified checksum {:02x}", m_current_sample_or_frame, calculated_header_checksum, specified_header_checksum); - dbgln_if(AFLACLOADER_DEBUG, "Frame: {} samples, {}bit {}Hz, channeltype {:x}, {} number {}, header checksum {:02x}{}", sample_count, bit_depth, frame_sample_rate, channel_type_num, blocking_strategy ? "sample" : "frame", m_current_sample_or_frame, specified_checksum, specified_checksum != calculated_checksum ? " (checksum error)"sv : ""sv); + dbgln_if(AFLACLOADER_DEBUG, "Frame: {} samples, {}bit {}Hz, channeltype {:x}, {} number {}, header checksum {:02x}{}", sample_count, bit_depth, frame_sample_rate, channel_type_num, blocking_strategy ? "sample" : "frame", m_current_sample_or_frame, specified_header_checksum, specified_header_checksum != calculated_header_checksum ? " (checksum error)"sv : ""sv); m_current_frame = FlacFrameHeader { sample_count, @@ -466,9 +465,11 @@ LoaderSamples FlacLoaderPlugin::next_frame() bit_stream.align_to_byte_boundary(); // 11.23. FRAME_FOOTER - // TODO: check checksum, see above - [[maybe_unused]] u16 footer_checksum = TRY(bit_stream.read_bits(16)); - dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {}", footer_checksum); + auto const calculated_frame_checksum = frame_checksum_stream->digest(); + auto const specified_frame_checksum = TRY(bit_stream.read_bits(16)); + if (calculated_frame_checksum != specified_frame_checksum) + dbgln("FLAC frame {}: Calculated frame checksum {:04x} is different from specified checksum {:04x}", m_current_sample_or_frame, calculated_frame_checksum, specified_frame_checksum); + dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {:04x}{}", specified_frame_checksum, specified_frame_checksum != calculated_frame_checksum ? " (checksum error)"sv : ""sv); FixedArray samples; diff --git a/Userland/Libraries/LibAudio/FlacTypes.h b/Userland/Libraries/LibAudio/FlacTypes.h index 36f9265e2b..8b5d4d7eb8 100644 --- a/Userland/Libraries/LibAudio/FlacTypes.h +++ b/Userland/Libraries/LibAudio/FlacTypes.h @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Audio { @@ -29,6 +30,11 @@ namespace Audio { static constexpr u8 flac_polynomial = 0x07; using FlacFrameHeaderCRC = Crypto::Checksum::CRC8; +// 11.23. FRAME_FOOTER +// The polynomial used here is known as CRC-16-IBM. +static constexpr u16 ibm_polynomial = 0xA001; +using IBMCRC = Crypto::Checksum::CRC16; + // 11.8 BLOCK_TYPE (7 bits) enum class FlacMetadataBlockType : u8 { STREAMINFO = 0, // Important data about the audio format