mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:07:45 +00:00
LibAudio: Calculate and verify frame checksum
This is the second of three checksums that FLAC provides, verifying all of a frame's data.
This commit is contained in:
parent
fb37587efe
commit
e45a666419
2 changed files with 19 additions and 12 deletions
|
@ -384,10 +384,9 @@ LoaderSamples FlacLoaderPlugin::next_frame()
|
||||||
dbgln("FLAC Warning: Inserting seek point for sample {} failed: {}", sample_index, maybe_error.release_error());
|
dbgln("FLAC Warning: Inserting seek point for sample {} failed: {}", sample_index, maybe_error.release_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto checksum_stream = TRY(try_make<Crypto::Checksum::ChecksummingStream<FlacFrameHeaderCRC>>(MaybeOwned<Stream>(*m_stream)));
|
auto frame_checksum_stream = TRY(try_make<Crypto::Checksum::ChecksummingStream<IBMCRC>>(MaybeOwned<Stream>(*m_stream)));
|
||||||
BigEndianInputBitStream bit_stream { MaybeOwned<Stream> { *checksum_stream } };
|
auto header_checksum_stream = TRY(try_make<Crypto::Checksum::ChecksummingStream<FlacFrameHeaderCRC>>(MaybeOwned<Stream>(*frame_checksum_stream)));
|
||||||
|
BigEndianInputBitStream bit_stream { MaybeOwned<Stream> { *header_checksum_stream } };
|
||||||
// TODO: Check the CRC-16 checksum by keeping track of read data.
|
|
||||||
|
|
||||||
// 11.22. FRAME_HEADER
|
// 11.22. FRAME_HEADER
|
||||||
u16 sync_code = TRY(bit_stream.read_bits<u16>(14));
|
u16 sync_code = TRY(bit_stream.read_bits<u16>(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.
|
// 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
|
// 11.22.11. FRAME CRC
|
||||||
u8 specified_checksum = TRY(bit_stream.read_bits<u8>(8));
|
u8 specified_header_checksum = TRY(bit_stream.read_bits<u8>(8));
|
||||||
VERIFY(bit_stream.is_aligned_to_byte_boundary());
|
VERIFY(bit_stream.is_aligned_to_byte_boundary());
|
||||||
if (specified_checksum != calculated_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_checksum, specified_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 {
|
m_current_frame = FlacFrameHeader {
|
||||||
sample_count,
|
sample_count,
|
||||||
|
@ -466,9 +465,11 @@ LoaderSamples FlacLoaderPlugin::next_frame()
|
||||||
bit_stream.align_to_byte_boundary();
|
bit_stream.align_to_byte_boundary();
|
||||||
|
|
||||||
// 11.23. FRAME_FOOTER
|
// 11.23. FRAME_FOOTER
|
||||||
// TODO: check checksum, see above
|
auto const calculated_frame_checksum = frame_checksum_stream->digest();
|
||||||
[[maybe_unused]] u16 footer_checksum = TRY(bit_stream.read_bits<u16>(16));
|
auto const specified_frame_checksum = TRY(bit_stream.read_bits<u16>(16));
|
||||||
dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {}", footer_checksum);
|
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<Sample> samples;
|
FixedArray<Sample> samples;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
|
#include <LibCrypto/Checksum/CRC16.h>
|
||||||
#include <LibCrypto/Checksum/CRC8.h>
|
#include <LibCrypto/Checksum/CRC8.h>
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
@ -29,6 +30,11 @@ namespace Audio {
|
||||||
static constexpr u8 flac_polynomial = 0x07;
|
static constexpr u8 flac_polynomial = 0x07;
|
||||||
using FlacFrameHeaderCRC = Crypto::Checksum::CRC8<flac_polynomial>;
|
using FlacFrameHeaderCRC = Crypto::Checksum::CRC8<flac_polynomial>;
|
||||||
|
|
||||||
|
// 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<ibm_polynomial>;
|
||||||
|
|
||||||
// 11.8 BLOCK_TYPE (7 bits)
|
// 11.8 BLOCK_TYPE (7 bits)
|
||||||
enum class FlacMetadataBlockType : u8 {
|
enum class FlacMetadataBlockType : u8 {
|
||||||
STREAMINFO = 0, // Important data about the audio format
|
STREAMINFO = 0, // Important data about the audio format
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue