1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 21:08:12 +00:00

LibAudio: Stop using and remove LOADER_TRY

It's no longer needed now that this code uses ErrorOr instead of Result.

Ran:

    rg -lw LOADER_TRY Userland/Libraries/LibAudio \
        | xargs sed -i '' 's/LOADER_TRY/TRY/g'

...and then manually fixed up Userland/Libraries/LibAudio/LoaderError.h
to not redefine TRY but instead remove the now-unused LOADER_TRY,
and ran clang-format.
This commit is contained in:
Nico Weber 2023-07-04 09:26:35 -04:00 committed by Andrew Kaster
parent 9594b79d38
commit 5619bb3e04
6 changed files with 166 additions and 177 deletions

View file

@ -62,15 +62,15 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
BigEndianInputBitStream bit_input { MaybeOwned<Stream>(*m_stream) }; BigEndianInputBitStream bit_input { MaybeOwned<Stream>(*m_stream) };
// A mixture of VERIFY and the non-crashing TRY(). // A mixture of VERIFY and the non-crashing TRY().
#define FLAC_VERIFY(check, category, msg) \ #define FLAC_VERIFY(check, category, msg) \
do { \ do { \
if (!(check)) { \ if (!(check)) { \
return LoaderError { category, LOADER_TRY(m_stream->tell()), DeprecatedString::formatted("FLAC header: {}", msg) }; \ return LoaderError { category, TRY(m_stream->tell()), DeprecatedString::formatted("FLAC header: {}", msg) }; \
} \ } \
} while (0) } while (0)
// Magic number // Magic number
u32 flac = LOADER_TRY(bit_input.read_bits<u32>(32)); u32 flac = TRY(bit_input.read_bits<u32>(32));
m_data_start_location += 4; m_data_start_location += 4;
FLAC_VERIFY(flac == 0x664C6143, LoaderError::Category::Format, "Magic number must be 'flaC'"); // "flaC" FLAC_VERIFY(flac == 0x664C6143, LoaderError::Category::Format, "Magic number must be 'flaC'"); // "flaC"
@ -81,17 +81,17 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
BigEndianInputBitStream streaminfo_data { MaybeOwned<Stream>(streaminfo_data_memory) }; BigEndianInputBitStream streaminfo_data { MaybeOwned<Stream>(streaminfo_data_memory) };
// 11.10 METADATA_BLOCK_STREAMINFO // 11.10 METADATA_BLOCK_STREAMINFO
m_min_block_size = LOADER_TRY(streaminfo_data.read_bits<u16>(16)); m_min_block_size = TRY(streaminfo_data.read_bits<u16>(16));
FLAC_VERIFY(m_min_block_size >= 16, LoaderError::Category::Format, "Minimum block size must be 16"); FLAC_VERIFY(m_min_block_size >= 16, LoaderError::Category::Format, "Minimum block size must be 16");
m_max_block_size = LOADER_TRY(streaminfo_data.read_bits<u16>(16)); m_max_block_size = TRY(streaminfo_data.read_bits<u16>(16));
FLAC_VERIFY(m_max_block_size >= 16, LoaderError::Category::Format, "Maximum block size"); FLAC_VERIFY(m_max_block_size >= 16, LoaderError::Category::Format, "Maximum block size");
m_min_frame_size = LOADER_TRY(streaminfo_data.read_bits<u32>(24)); m_min_frame_size = TRY(streaminfo_data.read_bits<u32>(24));
m_max_frame_size = LOADER_TRY(streaminfo_data.read_bits<u32>(24)); m_max_frame_size = TRY(streaminfo_data.read_bits<u32>(24));
m_sample_rate = LOADER_TRY(streaminfo_data.read_bits<u32>(20)); m_sample_rate = TRY(streaminfo_data.read_bits<u32>(20));
FLAC_VERIFY(m_sample_rate <= 655350, LoaderError::Category::Format, "Sample rate"); FLAC_VERIFY(m_sample_rate <= 655350, LoaderError::Category::Format, "Sample rate");
m_num_channels = LOADER_TRY(streaminfo_data.read_bits<u8>(3)) + 1; // 0 = one channel m_num_channels = TRY(streaminfo_data.read_bits<u8>(3)) + 1; // 0 = one channel
m_bits_per_sample = LOADER_TRY(streaminfo_data.read_bits<u8>(5)) + 1; m_bits_per_sample = TRY(streaminfo_data.read_bits<u8>(5)) + 1;
if (m_bits_per_sample <= 8) { if (m_bits_per_sample <= 8) {
// FIXME: Signed/Unsigned issues? // FIXME: Signed/Unsigned issues?
m_sample_format = PcmSampleFormat::Uint8; m_sample_format = PcmSampleFormat::Uint8;
@ -105,7 +105,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
FLAC_VERIFY(false, LoaderError::Category::Format, "Sample bit depth too large"); FLAC_VERIFY(false, LoaderError::Category::Format, "Sample bit depth too large");
} }
m_total_samples = LOADER_TRY(streaminfo_data.read_bits<u64>(36)); m_total_samples = TRY(streaminfo_data.read_bits<u64>(36));
if (m_total_samples == 0) { if (m_total_samples == 0) {
// "A value of zero here means the number of total samples is unknown." // "A value of zero here means the number of total samples is unknown."
dbgln("FLAC Warning: File has unknown amount of samples, the loader will not stop before EOF"); dbgln("FLAC Warning: File has unknown amount of samples, the loader will not stop before EOF");
@ -113,7 +113,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
} }
VERIFY(streaminfo_data.is_aligned_to_byte_boundary()); VERIFY(streaminfo_data.is_aligned_to_byte_boundary());
LOADER_TRY(streaminfo_data.read_until_filled({ m_md5_checksum, sizeof(m_md5_checksum) })); TRY(streaminfo_data.read_until_filled({ m_md5_checksum, sizeof(m_md5_checksum) }));
// Parse other blocks // Parse other blocks
[[maybe_unused]] u16 meta_blocks_parsed = 1; [[maybe_unused]] u16 meta_blocks_parsed = 1;
@ -158,39 +158,39 @@ MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block)
PictureData picture; PictureData picture;
picture.type = static_cast<ID3PictureType>(LOADER_TRY(picture_block_bytes.read_bits(32))); picture.type = static_cast<ID3PictureType>(TRY(picture_block_bytes.read_bits(32)));
auto const mime_string_length = LOADER_TRY(picture_block_bytes.read_bits(32)); auto const mime_string_length = TRY(picture_block_bytes.read_bits(32));
auto offset_before_seeking = memory_stream.offset(); auto offset_before_seeking = memory_stream.offset();
if (offset_before_seeking + mime_string_length >= block.data.size()) if (offset_before_seeking + mime_string_length >= block.data.size())
return LoaderError { LoaderError::Category::Format, LOADER_TRY(m_stream->tell()), "Picture MIME type exceeds available data" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Picture MIME type exceeds available data" };
// "The MIME type string, in printable ASCII characters 0x20-0x7E." // "The MIME type string, in printable ASCII characters 0x20-0x7E."
picture.mime_string = LOADER_TRY(String::from_stream(memory_stream, mime_string_length)); picture.mime_string = TRY(String::from_stream(memory_stream, mime_string_length));
for (auto code_point : picture.mime_string.code_points()) { for (auto code_point : picture.mime_string.code_points()) {
if (code_point < 0x20 || code_point > 0x7E) if (code_point < 0x20 || code_point > 0x7E)
return LoaderError { LoaderError::Category::Format, LOADER_TRY(m_stream->tell()), "Picture MIME type is not ASCII in range 0x20 - 0x7E" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Picture MIME type is not ASCII in range 0x20 - 0x7E" };
} }
auto const description_string_length = LOADER_TRY(picture_block_bytes.read_bits(32)); auto const description_string_length = TRY(picture_block_bytes.read_bits(32));
offset_before_seeking = memory_stream.offset(); offset_before_seeking = memory_stream.offset();
if (offset_before_seeking + description_string_length >= block.data.size()) if (offset_before_seeking + description_string_length >= block.data.size())
return LoaderError { LoaderError::Category::Format, LOADER_TRY(m_stream->tell()), "Picture description exceeds available data" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Picture description exceeds available data" };
picture.description_string = LOADER_TRY(String::from_stream(memory_stream, description_string_length)); picture.description_string = TRY(String::from_stream(memory_stream, description_string_length));
picture.width = LOADER_TRY(picture_block_bytes.read_bits(32)); picture.width = TRY(picture_block_bytes.read_bits(32));
picture.height = LOADER_TRY(picture_block_bytes.read_bits(32)); picture.height = TRY(picture_block_bytes.read_bits(32));
picture.color_depth = LOADER_TRY(picture_block_bytes.read_bits(32)); picture.color_depth = TRY(picture_block_bytes.read_bits(32));
picture.colors = LOADER_TRY(picture_block_bytes.read_bits(32)); picture.colors = TRY(picture_block_bytes.read_bits(32));
auto const picture_size = LOADER_TRY(picture_block_bytes.read_bits(32)); auto const picture_size = TRY(picture_block_bytes.read_bits(32));
offset_before_seeking = memory_stream.offset(); offset_before_seeking = memory_stream.offset();
if (offset_before_seeking + picture_size > block.data.size()) if (offset_before_seeking + picture_size > block.data.size())
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(TRY(m_stream->tell())), "Picture size exceeds available data" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(TRY(m_stream->tell())), "Picture size exceeds available data" };
LOADER_TRY(memory_stream.seek(picture_size, SeekMode::FromCurrentPosition)); TRY(memory_stream.seek(picture_size, SeekMode::FromCurrentPosition));
picture.data = Vector<u8> { block.data.bytes().slice(offset_before_seeking, picture_size) }; picture.data = Vector<u8> { block.data.bytes().slice(offset_before_seeking, picture_size) };
m_pictures.append(move(picture)); m_pictures.append(move(picture));
@ -216,10 +216,10 @@ MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block)
BigEndianInputBitStream seektable_bytes { MaybeOwned<Stream>(memory_stream) }; BigEndianInputBitStream seektable_bytes { MaybeOwned<Stream>(memory_stream) };
for (size_t i = 0; i < block.length / 18; ++i) { for (size_t i = 0; i < block.length / 18; ++i) {
// 11.14. SEEKPOINT // 11.14. SEEKPOINT
u64 sample_index = LOADER_TRY(seektable_bytes.read_bits<u64>(64)); u64 sample_index = TRY(seektable_bytes.read_bits<u64>(64));
u64 byte_offset = LOADER_TRY(seektable_bytes.read_bits<u64>(64)); u64 byte_offset = TRY(seektable_bytes.read_bits<u64>(64));
// The sample count of a seek point is not relevant to us. // The sample count of a seek point is not relevant to us.
[[maybe_unused]] u16 sample_count = LOADER_TRY(seektable_bytes.read_bits<u16>(16)); [[maybe_unused]] u16 sample_count = TRY(seektable_bytes.read_bits<u16>(16));
// Placeholder, to be ignored. // Placeholder, to be ignored.
if (sample_index == 0xFFFFFFFFFFFFFFFF) if (sample_index == 0xFFFFFFFFFFFFFFFF)
continue; continue;
@ -238,13 +238,13 @@ MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block)
ErrorOr<FlacRawMetadataBlock, LoaderError> FlacLoaderPlugin::next_meta_block(BigEndianInputBitStream& bit_input) ErrorOr<FlacRawMetadataBlock, LoaderError> FlacLoaderPlugin::next_meta_block(BigEndianInputBitStream& bit_input)
{ {
// 11.7 METADATA_BLOCK_HEADER // 11.7 METADATA_BLOCK_HEADER
bool is_last_block = LOADER_TRY(bit_input.read_bit()); bool is_last_block = TRY(bit_input.read_bit());
// The block type enum constants agree with the specification // The block type enum constants agree with the specification
FlacMetadataBlockType type = (FlacMetadataBlockType)LOADER_TRY(bit_input.read_bits<u8>(7)); FlacMetadataBlockType type = (FlacMetadataBlockType)TRY(bit_input.read_bits<u8>(7));
m_data_start_location += 1; m_data_start_location += 1;
FLAC_VERIFY(type != FlacMetadataBlockType::INVALID, LoaderError::Category::Format, "Invalid metadata block"); FLAC_VERIFY(type != FlacMetadataBlockType::INVALID, LoaderError::Category::Format, "Invalid metadata block");
u32 block_length = LOADER_TRY(bit_input.read_bits<u32>(24)); u32 block_length = TRY(bit_input.read_bits<u32>(24));
m_data_start_location += 3; m_data_start_location += 3;
// Blocks can be zero-sized, which would trip up the raw data reader below. // Blocks can be zero-sized, which would trip up the raw data reader below.
if (block_length == 0) if (block_length == 0)
@ -252,13 +252,13 @@ ErrorOr<FlacRawMetadataBlock, LoaderError> FlacLoaderPlugin::next_meta_block(Big
.is_last_block = is_last_block, .is_last_block = is_last_block,
.type = type, .type = type,
.length = 0, .length = 0,
.data = LOADER_TRY(ByteBuffer::create_uninitialized(0)) .data = TRY(ByteBuffer::create_uninitialized(0))
}; };
auto block_data_result = ByteBuffer::create_uninitialized(block_length); auto block_data_result = ByteBuffer::create_uninitialized(block_length);
FLAC_VERIFY(!block_data_result.is_error(), LoaderError::Category::IO, "Out of memory"); FLAC_VERIFY(!block_data_result.is_error(), LoaderError::Category::IO, "Out of memory");
auto block_data = block_data_result.release_value(); auto block_data = block_data_result.release_value();
LOADER_TRY(bit_input.read_until_filled(block_data)); TRY(bit_input.read_until_filled(block_data));
m_data_start_location += block_length; m_data_start_location += block_length;
return FlacRawMetadataBlock { return FlacRawMetadataBlock {
@ -288,7 +288,7 @@ MaybeLoaderError FlacLoaderPlugin::seek(int int_sample_index)
// No seektable or no fitting entry: Perform normal forward read // No seektable or no fitting entry: Perform normal forward read
if (!maybe_target_seekpoint.has_value()) { if (!maybe_target_seekpoint.has_value()) {
if (sample_index < m_loaded_samples) { if (sample_index < m_loaded_samples) {
LOADER_TRY(m_stream->seek(m_data_start_location, SeekMode::SetPosition)); TRY(m_stream->seek(m_data_start_location, SeekMode::SetPosition));
m_loaded_samples = 0; m_loaded_samples = 0;
} }
if (sample_index - m_loaded_samples == 0) if (sample_index - m_loaded_samples == 0)
@ -381,50 +381,50 @@ LoaderSamples FlacLoaderPlugin::next_frame()
// TODO: Check the CRC-16 checksum by keeping track of read data. // TODO: Check the CRC-16 checksum by keeping track of read data.
// 11.22. FRAME_HEADER // 11.22. FRAME_HEADER
u16 sync_code = LOADER_TRY(bit_stream.read_bits<u16>(14)); u16 sync_code = TRY(bit_stream.read_bits<u16>(14));
FLAC_VERIFY(sync_code == 0b11111111111110, LoaderError::Category::Format, "Sync code"); FLAC_VERIFY(sync_code == 0b11111111111110, LoaderError::Category::Format, "Sync code");
bool reserved_bit = LOADER_TRY(bit_stream.read_bit()); bool reserved_bit = TRY(bit_stream.read_bit());
FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header bit"); FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header bit");
// 11.22.2. BLOCKING STRATEGY // 11.22.2. BLOCKING STRATEGY
[[maybe_unused]] bool blocking_strategy = LOADER_TRY(bit_stream.read_bit()); [[maybe_unused]] bool blocking_strategy = TRY(bit_stream.read_bit());
u32 sample_count = TRY(convert_sample_count_code(LOADER_TRY(bit_stream.read_bits<u8>(4)))); u32 sample_count = TRY(convert_sample_count_code(TRY(bit_stream.read_bits<u8>(4))));
u32 frame_sample_rate = TRY(convert_sample_rate_code(LOADER_TRY(bit_stream.read_bits<u8>(4)))); u32 frame_sample_rate = TRY(convert_sample_rate_code(TRY(bit_stream.read_bits<u8>(4))));
u8 channel_type_num = LOADER_TRY(bit_stream.read_bits<u8>(4)); u8 channel_type_num = TRY(bit_stream.read_bits<u8>(4));
FLAC_VERIFY(channel_type_num < 0b1011, LoaderError::Category::Format, "Channel assignment"); FLAC_VERIFY(channel_type_num < 0b1011, LoaderError::Category::Format, "Channel assignment");
FlacFrameChannelType channel_type = (FlacFrameChannelType)channel_type_num; FlacFrameChannelType channel_type = (FlacFrameChannelType)channel_type_num;
u8 bit_depth = TRY(convert_bit_depth_code(LOADER_TRY(bit_stream.read_bits<u8>(3)))); u8 bit_depth = TRY(convert_bit_depth_code(TRY(bit_stream.read_bits<u8>(3))));
reserved_bit = LOADER_TRY(bit_stream.read_bit()); reserved_bit = TRY(bit_stream.read_bit());
FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header end bit"); FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header end bit");
// 11.22.8. CODED NUMBER // 11.22.8. CODED NUMBER
m_current_sample_or_frame = LOADER_TRY(read_utf8_char(bit_stream)); m_current_sample_or_frame = TRY(read_utf8_char(bit_stream));
// Conditional header variables // Conditional header variables
// 11.22.9. BLOCK SIZE INT // 11.22.9. BLOCK SIZE INT
if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_8) { if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_8) {
sample_count = LOADER_TRY(bit_stream.read_bits<u32>(8)) + 1; sample_count = TRY(bit_stream.read_bits<u32>(8)) + 1;
} else if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_16) { } else if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_16) {
sample_count = LOADER_TRY(bit_stream.read_bits<u32>(16)) + 1; sample_count = TRY(bit_stream.read_bits<u32>(16)) + 1;
} }
// 11.22.10. SAMPLE RATE INT // 11.22.10. SAMPLE RATE INT
if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_8) { if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_8) {
frame_sample_rate = LOADER_TRY(bit_stream.read_bits<u32>(8)) * 1000; frame_sample_rate = TRY(bit_stream.read_bits<u32>(8)) * 1000;
} else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16) { } else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16) {
frame_sample_rate = LOADER_TRY(bit_stream.read_bits<u32>(16)); frame_sample_rate = TRY(bit_stream.read_bits<u32>(16));
} else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16X10) { } else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16X10) {
frame_sample_rate = LOADER_TRY(bit_stream.read_bits<u32>(16)) * 10; frame_sample_rate = TRY(bit_stream.read_bits<u32>(16)) * 10;
} }
// 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_checksum = checksum_stream->digest();
// 11.22.11. FRAME CRC // 11.22.11. FRAME CRC
u8 specified_checksum = LOADER_TRY(bit_stream.read_bits<u8>(8)); u8 specified_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_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); dbgln("FLAC frame {}: Calculated header checksum {:02x} is different from specified checksum {:02x}", m_current_sample_or_frame, calculated_checksum, specified_checksum);
@ -455,7 +455,7 @@ LoaderSamples FlacLoaderPlugin::next_frame()
// 11.23. FRAME_FOOTER // 11.23. FRAME_FOOTER
// TODO: check checksum, see above // TODO: check checksum, see above
[[maybe_unused]] u16 footer_checksum = LOADER_TRY(bit_stream.read_bits<u16>(16)); [[maybe_unused]] u16 footer_checksum = TRY(bit_stream.read_bits<u16>(16));
dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {}", footer_checksum); dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {}", footer_checksum);
float sample_rescale = 1 / static_cast<float>(1 << (m_current_frame->bit_depth - 1)); float sample_rescale = 1 / static_cast<float>(1 << (m_current_frame->bit_depth - 1));
@ -628,11 +628,11 @@ ErrorOr<FlacSubframeHeader, LoaderError> FlacLoaderPlugin::next_subframe_header(
} }
// zero-bit padding // zero-bit padding
if (LOADER_TRY(bit_stream.read_bit()) != 0) if (TRY(bit_stream.read_bit()) != 0)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Zero bit padding" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Zero bit padding" };
// 11.25.1. SUBFRAME TYPE // 11.25.1. SUBFRAME TYPE
u8 subframe_code = LOADER_TRY(bit_stream.read_bits<u8>(6)); u8 subframe_code = TRY(bit_stream.read_bits<u8>(6));
if ((subframe_code >= 0b000010 && subframe_code <= 0b000111) || (subframe_code > 0b001100 && subframe_code < 0b100000)) if ((subframe_code >= 0b000010 && subframe_code <= 0b000111) || (subframe_code > 0b001100 && subframe_code < 0b100000))
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Subframe type" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Subframe type" };
@ -651,12 +651,12 @@ ErrorOr<FlacSubframeHeader, LoaderError> FlacLoaderPlugin::next_subframe_header(
} }
// 11.25.2. WASTED BITS PER SAMPLE FLAG // 11.25.2. WASTED BITS PER SAMPLE FLAG
bool has_wasted_bits = LOADER_TRY(bit_stream.read_bit()); bool has_wasted_bits = TRY(bit_stream.read_bit());
u8 k = 0; u8 k = 0;
if (has_wasted_bits) { if (has_wasted_bits) {
bool current_k_bit = 0; bool current_k_bit = 0;
do { do {
current_k_bit = LOADER_TRY(bit_stream.read_bit()); current_k_bit = TRY(bit_stream.read_bit());
++k; ++k;
} while (current_k_bit != 1); } while (current_k_bit != 1);
} }
@ -676,7 +676,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::parse_subframe(FlacSubframeH
switch (subframe_header.type) { switch (subframe_header.type) {
case FlacSubframeType::Constant: { case FlacSubframeType::Constant: {
// 11.26. SUBFRAME_CONSTANT // 11.26. SUBFRAME_CONSTANT
u64 constant_value = LOADER_TRY(bit_input.read_bits<u64>(subframe_header.bits_per_sample - subframe_header.wasted_bits_per_sample)); u64 constant_value = TRY(bit_input.read_bits<u64>(subframe_header.bits_per_sample - subframe_header.wasted_bits_per_sample));
dbgln_if(AFLACLOADER_DEBUG, "Constant subframe: {}", constant_value); dbgln_if(AFLACLOADER_DEBUG, "Constant subframe: {}", constant_value);
samples.ensure_capacity(m_current_frame->sample_count); samples.ensure_capacity(m_current_frame->sample_count);
@ -728,7 +728,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_verbatim(FlacSubframe
VERIFY(subframe.bits_per_sample - subframe.wasted_bits_per_sample != 0); VERIFY(subframe.bits_per_sample - subframe.wasted_bits_per_sample != 0);
for (size_t i = 0; i < m_current_frame->sample_count; ++i) { for (size_t i = 0; i < m_current_frame->sample_count; ++i) {
decoded.unchecked_append(sign_extend( decoded.unchecked_append(sign_extend(
LOADER_TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)), TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)),
subframe.bits_per_sample - subframe.wasted_bits_per_sample)); subframe.bits_per_sample - subframe.wasted_bits_per_sample));
} }
@ -750,24 +750,24 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_custom_lpc(FlacSubfra
// warm-up samples // warm-up samples
for (auto i = 0; i < subframe.order; ++i) { for (auto i = 0; i < subframe.order; ++i) {
decoded.unchecked_append(sign_extend( decoded.unchecked_append(sign_extend(
LOADER_TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)), TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)),
subframe.bits_per_sample - subframe.wasted_bits_per_sample)); subframe.bits_per_sample - subframe.wasted_bits_per_sample));
} }
// precision of the coefficients // precision of the coefficients
u8 lpc_precision = LOADER_TRY(bit_input.read_bits<u8>(4)); u8 lpc_precision = TRY(bit_input.read_bits<u8>(4));
if (lpc_precision == 0b1111) if (lpc_precision == 0b1111)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Invalid linear predictor coefficient precision" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Invalid linear predictor coefficient precision" };
lpc_precision += 1; lpc_precision += 1;
// shift needed on the data (signed!) // shift needed on the data (signed!)
i8 lpc_shift = static_cast<i8>(sign_extend(LOADER_TRY(bit_input.read_bits<u8>(5)), 5)); i8 lpc_shift = static_cast<i8>(sign_extend(TRY(bit_input.read_bits<u8>(5)), 5));
Vector<i64> coefficients; Vector<i64> coefficients;
coefficients.ensure_capacity(subframe.order); coefficients.ensure_capacity(subframe.order);
// read coefficients // read coefficients
for (auto i = 0; i < subframe.order; ++i) { for (auto i = 0; i < subframe.order; ++i) {
u64 raw_coefficient = LOADER_TRY(bit_input.read_bits<u64>(lpc_precision)); u64 raw_coefficient = TRY(bit_input.read_bits<u64>(lpc_precision));
i64 coefficient = sign_extend(raw_coefficient, lpc_precision); i64 coefficient = sign_extend(raw_coefficient, lpc_precision);
coefficients.unchecked_append(coefficient); coefficients.unchecked_append(coefficient);
} }
@ -809,7 +809,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_fixed_lpc(FlacSubfram
// warm-up samples // warm-up samples
for (auto i = 0; i < subframe.order; ++i) { for (auto i = 0; i < subframe.order; ++i) {
decoded.unchecked_append(sign_extend( decoded.unchecked_append(sign_extend(
LOADER_TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)), TRY(bit_input.read_bits<u64>(subframe.bits_per_sample - subframe.wasted_bits_per_sample)),
subframe.bits_per_sample - subframe.wasted_bits_per_sample)); subframe.bits_per_sample - subframe.wasted_bits_per_sample));
} }
@ -871,8 +871,8 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_fixed_lpc(FlacSubfram
MaybeLoaderError FlacLoaderPlugin::decode_residual(Vector<i64>& decoded, FlacSubframeHeader& subframe, BigEndianInputBitStream& bit_input) MaybeLoaderError FlacLoaderPlugin::decode_residual(Vector<i64>& decoded, FlacSubframeHeader& subframe, BigEndianInputBitStream& bit_input)
{ {
// 11.30.1. RESIDUAL_CODING_METHOD // 11.30.1. RESIDUAL_CODING_METHOD
auto residual_mode = static_cast<FlacResidualMode>(LOADER_TRY(bit_input.read_bits<u8>(2))); auto residual_mode = static_cast<FlacResidualMode>(TRY(bit_input.read_bits<u8>(2)));
u8 partition_order = LOADER_TRY(bit_input.read_bits<u8>(4)); u8 partition_order = TRY(bit_input.read_bits<u8>(4));
size_t partitions = 1 << partition_order; size_t partitions = 1 << partition_order;
if (partitions > m_current_frame->sample_count) if (partitions > m_current_frame->sample_count)
@ -903,7 +903,7 @@ MaybeLoaderError FlacLoaderPlugin::decode_residual(Vector<i64>& decoded, FlacSub
ALWAYS_INLINE ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_rice_partition(u8 partition_type, u32 partitions, u32 partition_index, FlacSubframeHeader& subframe, BigEndianInputBitStream& bit_input) ALWAYS_INLINE ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_rice_partition(u8 partition_type, u32 partitions, u32 partition_index, FlacSubframeHeader& subframe, BigEndianInputBitStream& bit_input)
{ {
// 11.30.2.2. EXP GOLOMB PARTITION ENCODING PARAMETER and 11.30.3.2. EXP-GOLOMB2 PARTITION ENCODING PARAMETER // 11.30.2.2. EXP GOLOMB PARTITION ENCODING PARAMETER and 11.30.3.2. EXP-GOLOMB2 PARTITION ENCODING PARAMETER
u8 k = LOADER_TRY(bit_input.read_bits<u8>(partition_type)); u8 k = TRY(bit_input.read_bits<u8>(partition_type));
u32 residual_sample_count; u32 residual_sample_count;
if (partitions == 0) if (partitions == 0)
@ -921,13 +921,13 @@ ALWAYS_INLINE ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_rice_pa
// escape code for unencoded binary partition // escape code for unencoded binary partition
if (k == (1 << partition_type) - 1) { if (k == (1 << partition_type) - 1) {
u8 unencoded_bps = LOADER_TRY(bit_input.read_bits<u8>(5)); u8 unencoded_bps = TRY(bit_input.read_bits<u8>(5));
for (size_t r = 0; r < residual_sample_count; ++r) { for (size_t r = 0; r < residual_sample_count; ++r) {
rice_partition[r] = LOADER_TRY(bit_input.read_bits<u8>(unencoded_bps)); rice_partition[r] = TRY(bit_input.read_bits<u8>(unencoded_bps));
} }
} else { } else {
for (size_t r = 0; r < residual_sample_count; ++r) { for (size_t r = 0; r < residual_sample_count; ++r) {
rice_partition[r] = LOADER_TRY(decode_unsigned_exp_golomb(k, bit_input)); rice_partition[r] = TRY(decode_unsigned_exp_golomb(k, bit_input));
} }
} }

View file

@ -44,12 +44,12 @@ static constexpr LoaderPluginInitializer s_initializers[] = {
ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(StringView path) ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(StringView path)
{ {
auto stream = LOADER_TRY(Core::InputBufferedFile::create(LOADER_TRY(Core::File::open(path, Core::File::OpenMode::Read)))); auto stream = TRY(Core::InputBufferedFile::create(TRY(Core::File::open(path, Core::File::OpenMode::Read))));
return adopt_ref(*new (nothrow) Loader(TRY(Loader::create_plugin(move(stream))))); return adopt_ref(*new (nothrow) Loader(TRY(Loader::create_plugin(move(stream)))));
} }
ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(Bytes buffer) ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(Bytes buffer)
{ {
auto stream = LOADER_TRY(try_make<FixedMemoryStream>(buffer)); auto stream = TRY(try_make<FixedMemoryStream>(buffer));
return adopt_ref(*new (nothrow) Loader(TRY(Loader::create_plugin(move(stream))))); return adopt_ref(*new (nothrow) Loader(TRY(Loader::create_plugin(move(stream)))));
} }
@ -70,7 +70,7 @@ LoaderSamples Loader::get_more_samples(size_t samples_to_read_from_input)
{ {
size_t remaining_samples = total_samples() - loaded_samples(); size_t remaining_samples = total_samples() - loaded_samples();
size_t samples_to_read = min(remaining_samples, samples_to_read_from_input); size_t samples_to_read = min(remaining_samples, samples_to_read_from_input);
auto samples = LOADER_TRY(FixedArray<Sample>::create(samples_to_read)); auto samples = TRY(FixedArray<Sample>::create(samples_to_read));
size_t sample_index = 0; size_t sample_index = 0;
@ -98,11 +98,11 @@ LoaderSamples Loader::get_more_samples(size_t samples_to_read_from_input)
if (count < chunk.size()) { if (count < chunk.size()) {
auto remaining_samples_count = chunk.size() - count; auto remaining_samples_count = chunk.size() - count;
// We will always have an empty buffer at this point! // We will always have an empty buffer at this point!
LOADER_TRY(m_buffer.try_append(chunk.span().offset(count), remaining_samples_count)); TRY(m_buffer.try_append(chunk.span().offset(count), remaining_samples_count));
} }
} else { } else {
// We're now past what the user requested. Transfer the entirety of the data into the buffer. // We're now past what the user requested. Transfer the entirety of the data into the buffer.
LOADER_TRY(m_buffer.try_append(chunk.data(), chunk.size())); TRY(m_buffer.try_append(chunk.data(), chunk.size()));
} }
sample_index += chunk.size(); sample_index += chunk.size();
} }

View file

@ -94,14 +94,3 @@ struct Formatter<Audio::LoaderError> : Formatter<FormatString> {
}; };
} }
// Convenience TRY-like macro to convert an Error to a LoaderError
#define LOADER_TRY(expression) \
({ \
auto&& _temporary_result = (expression); \
if (_temporary_result.is_error()) \
return LoaderError(_temporary_result.release_error()); \
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \
"Do not return a reference from a fallible expression"); \
_temporary_result.release_value(); \
})

View file

@ -49,13 +49,13 @@ bool MP3LoaderPlugin::sniff(SeekableStream& stream)
ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> MP3LoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream) ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> MP3LoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream)
{ {
auto loader = make<MP3LoaderPlugin>(move(stream)); auto loader = make<MP3LoaderPlugin>(move(stream));
LOADER_TRY(loader->initialize()); TRY(loader->initialize());
return loader; return loader;
} }
MaybeLoaderError MP3LoaderPlugin::initialize() MaybeLoaderError MP3LoaderPlugin::initialize()
{ {
m_bitstream = LOADER_TRY(try_make<BigEndianInputBitStream>(MaybeOwned<Stream>(*m_stream))); m_bitstream = TRY(try_make<BigEndianInputBitStream>(MaybeOwned<Stream>(*m_stream)));
TRY(synchronize()); TRY(synchronize());
@ -69,7 +69,7 @@ MaybeLoaderError MP3LoaderPlugin::initialize()
TRY(build_seek_table()); TRY(build_seek_table());
LOADER_TRY(m_stream->seek(0, SeekMode::SetPosition)); TRY(m_stream->seek(0, SeekMode::SetPosition));
return {}; return {};
} }
@ -80,7 +80,7 @@ MaybeLoaderError MP3LoaderPlugin::reset()
m_current_frame = {}; m_current_frame = {};
m_synthesis_buffer = {}; m_synthesis_buffer = {};
m_loaded_samples = 0; m_loaded_samples = 0;
LOADER_TRY(m_bit_reservoir.discard(m_bit_reservoir.used_buffer_size())); TRY(m_bit_reservoir.discard(m_bit_reservoir.used_buffer_size()));
m_bitstream->align_to_byte_boundary(); m_bitstream->align_to_byte_boundary();
return {}; return {};
} }
@ -89,12 +89,12 @@ MaybeLoaderError MP3LoaderPlugin::seek(int const position)
{ {
auto seek_entry = m_seek_table.seek_point_before(position); auto seek_entry = m_seek_table.seek_point_before(position);
if (seek_entry.has_value()) { if (seek_entry.has_value()) {
LOADER_TRY(m_stream->seek(seek_entry->byte_offset, SeekMode::SetPosition)); TRY(m_stream->seek(seek_entry->byte_offset, SeekMode::SetPosition));
m_loaded_samples = seek_entry->sample_index; m_loaded_samples = seek_entry->sample_index;
} }
m_current_frame = {}; m_current_frame = {};
m_synthesis_buffer = {}; m_synthesis_buffer = {};
LOADER_TRY(m_bit_reservoir.discard(m_bit_reservoir.used_buffer_size())); TRY(m_bit_reservoir.discard(m_bit_reservoir.used_buffer_size()));
m_bitstream->align_to_byte_boundary(); m_bitstream->align_to_byte_boundary();
return {}; return {};
} }
@ -104,7 +104,7 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> MP3LoaderPlugin::load_chunks(si
int samples_to_read = samples_to_read_from_input; int samples_to_read = samples_to_read_from_input;
Vector<FixedArray<Sample>> frames; Vector<FixedArray<Sample>> frames;
while (samples_to_read > 0) { while (samples_to_read > 0) {
FixedArray<Sample> samples = LOADER_TRY(FixedArray<Sample>::create(MP3::frame_size)); FixedArray<Sample> samples = TRY(FixedArray<Sample>::create(MP3::frame_size));
if (!m_current_frame.has_value()) { if (!m_current_frame.has_value()) {
auto maybe_frame = read_next_frame(); auto maybe_frame = read_next_frame();
@ -150,7 +150,7 @@ MaybeLoaderError MP3LoaderPlugin::build_seek_table()
m_bitstream->align_to_byte_boundary(); m_bitstream->align_to_byte_boundary();
while (!synchronize().is_error()) { while (!synchronize().is_error()) {
auto const frame_pos = -2 + LOADER_TRY(m_stream->seek(0, SeekMode::FromCurrentPosition)); auto const frame_pos = -2 + TRY(m_stream->seek(0, SeekMode::FromCurrentPosition));
auto error_or_header = read_header(); auto error_or_header = read_header();
if (error_or_header.is_error() || error_or_header.value().id != 1 || error_or_header.value().layer != 3) { if (error_or_header.is_error() || error_or_header.value().id != 1 || error_or_header.value().layer != 3) {
@ -160,9 +160,9 @@ MaybeLoaderError MP3LoaderPlugin::build_seek_table()
sample_count += MP3::frame_size; sample_count += MP3::frame_size;
if (frame_count % 10 == 0) if (frame_count % 10 == 0)
LOADER_TRY(m_seek_table.insert_seek_point({ static_cast<u64>(sample_count), frame_pos })); TRY(m_seek_table.insert_seek_point({ static_cast<u64>(sample_count), frame_pos }));
LOADER_TRY(m_stream->seek(error_or_header.value().frame_size - 6, SeekMode::FromCurrentPosition)); TRY(m_stream->seek(error_or_header.value().frame_size - 6, SeekMode::FromCurrentPosition));
// TODO: This is just here to clear the bitstream buffer. // TODO: This is just here to clear the bitstream buffer.
// Bitstream should have a method to sync its state to the underlying stream. // Bitstream should have a method to sync its state to the underlying stream.
@ -175,26 +175,26 @@ MaybeLoaderError MP3LoaderPlugin::build_seek_table()
ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::read_header() ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::read_header()
{ {
MP3::Header header; MP3::Header header;
header.id = LOADER_TRY(m_bitstream->read_bit()); header.id = TRY(m_bitstream->read_bit());
header.layer = MP3::Tables::LayerNumberLookup[LOADER_TRY(m_bitstream->read_bits(2))]; header.layer = MP3::Tables::LayerNumberLookup[TRY(m_bitstream->read_bits(2))];
if (header.layer <= 0) if (header.layer <= 0)
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid layer number." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid layer number." };
header.protection_bit = LOADER_TRY(m_bitstream->read_bit()); header.protection_bit = TRY(m_bitstream->read_bit());
header.bitrate = MP3::Tables::BitratesPerLayerLookup[header.layer - 1][LOADER_TRY(m_bitstream->read_bits(4))]; header.bitrate = MP3::Tables::BitratesPerLayerLookup[header.layer - 1][TRY(m_bitstream->read_bits(4))];
if (header.bitrate <= 0) if (header.bitrate <= 0)
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid bitrate." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid bitrate." };
header.samplerate = MP3::Tables::SampleratesLookup[LOADER_TRY(m_bitstream->read_bits(2))]; header.samplerate = MP3::Tables::SampleratesLookup[TRY(m_bitstream->read_bits(2))];
if (header.samplerate <= 0) if (header.samplerate <= 0)
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid samplerate." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame header contains invalid samplerate." };
header.padding_bit = LOADER_TRY(m_bitstream->read_bit()); header.padding_bit = TRY(m_bitstream->read_bit());
header.private_bit = LOADER_TRY(m_bitstream->read_bit()); header.private_bit = TRY(m_bitstream->read_bit());
header.mode = static_cast<MP3::Mode>(LOADER_TRY(m_bitstream->read_bits(2))); header.mode = static_cast<MP3::Mode>(TRY(m_bitstream->read_bits(2)));
header.mode_extension = static_cast<MP3::ModeExtension>(LOADER_TRY(m_bitstream->read_bits(2))); header.mode_extension = static_cast<MP3::ModeExtension>(TRY(m_bitstream->read_bits(2)));
header.copyright_bit = LOADER_TRY(m_bitstream->read_bit()); header.copyright_bit = TRY(m_bitstream->read_bit());
header.original_bit = LOADER_TRY(m_bitstream->read_bit()); header.original_bit = TRY(m_bitstream->read_bit());
header.emphasis = static_cast<MP3::Emphasis>(LOADER_TRY(m_bitstream->read_bits(2))); header.emphasis = static_cast<MP3::Emphasis>(TRY(m_bitstream->read_bits(2)));
if (!header.protection_bit) if (!header.protection_bit)
header.crc16 = LOADER_TRY(m_bitstream->read_bits<u16>(16)); header.crc16 = TRY(m_bitstream->read_bits<u16>(16));
header.frame_size = 144 * header.bitrate * 1000 / header.samplerate + header.padding_bit; header.frame_size = 144 * header.bitrate * 1000 / header.samplerate + header.padding_bit;
header.slot_count = header.frame_size - ((header.channel_count() == 2 ? 32 : 17) + (header.protection_bit ? 0 : 2) + 4); header.slot_count = header.frame_size - ((header.channel_count() == 2 ? 32 : 17) + (header.protection_bit ? 0 : 2) + 4);
return header; return header;
@ -204,7 +204,7 @@ MaybeLoaderError MP3LoaderPlugin::synchronize(BigEndianInputBitStream& stream, s
{ {
size_t one_counter = 0; size_t one_counter = 0;
while (one_counter < 12 && !stream.is_eof()) { while (one_counter < 12 && !stream.is_eof()) {
bool const bit = LOADER_TRY(stream.read_bit()); bool const bit = TRY(stream.read_bit());
one_counter = bit ? one_counter + 1 : 0; one_counter = bit ? one_counter + 1 : 0;
if (!bit) { if (!bit) {
stream.align_to_byte_boundary(); stream.align_to_byte_boundary();
@ -247,8 +247,8 @@ ErrorOr<MP3::MP3Frame, LoaderError> MP3LoaderPlugin::read_frame_data(MP3::Header
auto& buffer = maybe_buffer.value(); auto& buffer = maybe_buffer.value();
size_t old_reservoir_size = m_bit_reservoir.used_buffer_size(); size_t old_reservoir_size = m_bit_reservoir.used_buffer_size();
LOADER_TRY(m_bitstream->read_until_filled(buffer)); TRY(m_bitstream->read_until_filled(buffer));
LOADER_TRY(m_bit_reservoir.write_until_depleted(buffer)); TRY(m_bit_reservoir.write_until_depleted(buffer));
// If we don't have enough data in the reservoir to process this frame, skip it (but keep the data). // If we don't have enough data in the reservoir to process this frame, skip it (but keep the data).
if (old_reservoir_size < static_cast<size_t>(frame.main_data_begin)) if (old_reservoir_size < static_cast<size_t>(frame.main_data_begin))
@ -326,46 +326,46 @@ ErrorOr<MP3::MP3Frame, LoaderError> MP3LoaderPlugin::read_frame_data(MP3::Header
MaybeLoaderError MP3LoaderPlugin::read_side_information(MP3::MP3Frame& frame) MaybeLoaderError MP3LoaderPlugin::read_side_information(MP3::MP3Frame& frame)
{ {
frame.main_data_begin = LOADER_TRY(m_bitstream->read_bits(9)); frame.main_data_begin = TRY(m_bitstream->read_bits(9));
if (frame.header.channel_count() == 1) { if (frame.header.channel_count() == 1) {
frame.private_bits = LOADER_TRY(m_bitstream->read_bits(5)); frame.private_bits = TRY(m_bitstream->read_bits(5));
} else { } else {
frame.private_bits = LOADER_TRY(m_bitstream->read_bits(3)); frame.private_bits = TRY(m_bitstream->read_bits(3));
} }
for (size_t channel_index = 0; channel_index < frame.header.channel_count(); channel_index++) { for (size_t channel_index = 0; channel_index < frame.header.channel_count(); channel_index++) {
for (size_t scale_factor_selection_info_band = 0; scale_factor_selection_info_band < 4; scale_factor_selection_info_band++) { for (size_t scale_factor_selection_info_band = 0; scale_factor_selection_info_band < 4; scale_factor_selection_info_band++) {
frame.channels[channel_index].scale_factor_selection_info[scale_factor_selection_info_band] = LOADER_TRY(m_bitstream->read_bit()); frame.channels[channel_index].scale_factor_selection_info[scale_factor_selection_info_band] = TRY(m_bitstream->read_bit());
} }
} }
for (size_t granule_index = 0; granule_index < 2; granule_index++) { for (size_t granule_index = 0; granule_index < 2; granule_index++) {
for (size_t channel_index = 0; channel_index < frame.header.channel_count(); channel_index++) { for (size_t channel_index = 0; channel_index < frame.header.channel_count(); channel_index++) {
auto& granule = frame.channels[channel_index].granules[granule_index]; auto& granule = frame.channels[channel_index].granules[granule_index];
granule.part_2_3_length = LOADER_TRY(m_bitstream->read_bits(12)); granule.part_2_3_length = TRY(m_bitstream->read_bits(12));
granule.big_values = LOADER_TRY(m_bitstream->read_bits(9)); granule.big_values = TRY(m_bitstream->read_bits(9));
granule.global_gain = LOADER_TRY(m_bitstream->read_bits(8)); granule.global_gain = TRY(m_bitstream->read_bits(8));
granule.scalefac_compress = LOADER_TRY(m_bitstream->read_bits(4)); granule.scalefac_compress = TRY(m_bitstream->read_bits(4));
granule.window_switching_flag = LOADER_TRY(m_bitstream->read_bit()); granule.window_switching_flag = TRY(m_bitstream->read_bit());
if (granule.window_switching_flag) { if (granule.window_switching_flag) {
granule.block_type = static_cast<MP3::BlockType>(LOADER_TRY(m_bitstream->read_bits(2))); granule.block_type = static_cast<MP3::BlockType>(TRY(m_bitstream->read_bits(2)));
granule.mixed_block_flag = LOADER_TRY(m_bitstream->read_bit()); granule.mixed_block_flag = TRY(m_bitstream->read_bit());
for (size_t region = 0; region < 2; region++) for (size_t region = 0; region < 2; region++)
granule.table_select[region] = LOADER_TRY(m_bitstream->read_bits(5)); granule.table_select[region] = TRY(m_bitstream->read_bits(5));
for (size_t window = 0; window < 3; window++) for (size_t window = 0; window < 3; window++)
granule.sub_block_gain[window] = LOADER_TRY(m_bitstream->read_bits(3)); granule.sub_block_gain[window] = TRY(m_bitstream->read_bits(3));
granule.region0_count = (granule.block_type == MP3::BlockType::Short && !granule.mixed_block_flag) ? 8 : 7; granule.region0_count = (granule.block_type == MP3::BlockType::Short && !granule.mixed_block_flag) ? 8 : 7;
granule.region1_count = 36; granule.region1_count = 36;
} else { } else {
for (size_t region = 0; region < 3; region++) for (size_t region = 0; region < 3; region++)
granule.table_select[region] = LOADER_TRY(m_bitstream->read_bits(5)); granule.table_select[region] = TRY(m_bitstream->read_bits(5));
granule.region0_count = LOADER_TRY(m_bitstream->read_bits(4)); granule.region0_count = TRY(m_bitstream->read_bits(4));
granule.region1_count = LOADER_TRY(m_bitstream->read_bits(3)); granule.region1_count = TRY(m_bitstream->read_bits(3));
} }
granule.preflag = LOADER_TRY(m_bitstream->read_bit()); granule.preflag = TRY(m_bitstream->read_bit());
granule.scalefac_scale = LOADER_TRY(m_bitstream->read_bit()); granule.scalefac_scale = TRY(m_bitstream->read_bit());
granule.count1table_select = LOADER_TRY(m_bitstream->read_bit()); granule.count1table_select = TRY(m_bitstream->read_bit());
} }
} }
return {}; return {};
@ -551,21 +551,21 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
int y = entry.code->symbol.y; int y = entry.code->symbol.y;
if (x == 15 && tree->linbits > 0) { if (x == 15 && tree->linbits > 0) {
x += LOADER_TRY(reservoir.read_bits(tree->linbits)); x += TRY(reservoir.read_bits(tree->linbits));
granule_bits_read += tree->linbits; granule_bits_read += tree->linbits;
} }
if (x != 0) { if (x != 0) {
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
x = -x; x = -x;
granule_bits_read++; granule_bits_read++;
} }
if (y == 15 && tree->linbits > 0) { if (y == 15 && tree->linbits > 0) {
y += LOADER_TRY(reservoir.read_bits(tree->linbits)); y += TRY(reservoir.read_bits(tree->linbits));
granule_bits_read += tree->linbits; granule_bits_read += tree->linbits;
} }
if (y != 0) { if (y != 0) {
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
y = -y; y = -y;
granule_bits_read++; granule_bits_read++;
} }
@ -589,7 +589,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
if (v != 0) { if (v != 0) {
if (granule_bits_read >= granule.part_2_3_length) if (granule_bits_read >= granule.part_2_3_length)
break; break;
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
v = -v; v = -v;
granule_bits_read++; granule_bits_read++;
} }
@ -597,7 +597,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
if (w != 0) { if (w != 0) {
if (granule_bits_read >= granule.part_2_3_length) if (granule_bits_read >= granule.part_2_3_length)
break; break;
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
w = -w; w = -w;
granule_bits_read++; granule_bits_read++;
} }
@ -605,7 +605,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
if (x != 0) { if (x != 0) {
if (granule_bits_read >= granule.part_2_3_length) if (granule_bits_read >= granule.part_2_3_length)
break; break;
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
x = -x; x = -x;
granule_bits_read++; granule_bits_read++;
} }
@ -613,7 +613,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
if (y != 0) { if (y != 0) {
if (granule_bits_read >= granule.part_2_3_length) if (granule_bits_read >= granule.part_2_3_length)
break; break;
if (LOADER_TRY(reservoir.read_bit())) if (TRY(reservoir.read_bit()))
y = -y; y = -y;
granule_bits_read++; granule_bits_read++;
} }
@ -633,7 +633,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
// 2.4.3.4.6: "If there are more Huffman code bits than necessary to decode 576 values // 2.4.3.4.6: "If there are more Huffman code bits than necessary to decode 576 values
// they are regarded as stuffing bits and discarded." // they are regarded as stuffing bits and discarded."
for (size_t i = granule_bits_read; i < granule.part_2_3_length; i++) { for (size_t i = granule_bits_read; i < granule.part_2_3_length; i++) {
LOADER_TRY(reservoir.read_bit()); TRY(reservoir.read_bit());
} }
return {}; return {};

View file

@ -33,7 +33,7 @@ bool QOALoaderPlugin::sniff(SeekableStream& stream)
ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> QOALoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream) ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> QOALoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream)
{ {
auto loader = make<QOALoaderPlugin>(move(stream)); auto loader = make<QOALoaderPlugin>(move(stream));
LOADER_TRY(loader->initialize()); TRY(loader->initialize());
return loader; return loader;
} }
@ -46,46 +46,46 @@ MaybeLoaderError QOALoaderPlugin::initialize()
MaybeLoaderError QOALoaderPlugin::parse_header() MaybeLoaderError QOALoaderPlugin::parse_header()
{ {
u32 header_magic = LOADER_TRY(m_stream->read_value<BigEndian<u32>>()); u32 header_magic = TRY(m_stream->read_value<BigEndian<u32>>());
if (header_magic != QOA::magic) if (header_magic != QOA::magic)
return LoaderError { LoaderError::Category::Format, 0, "QOA header: Magic number must be 'qoaf'" }; return LoaderError { LoaderError::Category::Format, 0, "QOA header: Magic number must be 'qoaf'" };
m_total_samples = LOADER_TRY(m_stream->read_value<BigEndian<u32>>()); m_total_samples = TRY(m_stream->read_value<BigEndian<u32>>());
return {}; return {};
} }
MaybeLoaderError QOALoaderPlugin::load_one_frame(Span<Sample>& target, IsFirstFrame is_first_frame) MaybeLoaderError QOALoaderPlugin::load_one_frame(Span<Sample>& target, IsFirstFrame is_first_frame)
{ {
QOA::FrameHeader header = LOADER_TRY(m_stream->read_value<QOA::FrameHeader>()); QOA::FrameHeader header = TRY(m_stream->read_value<QOA::FrameHeader>());
if (header.num_channels > 8) if (header.num_channels > 8)
dbgln("QOALoader: Warning: QOA frame at {} has more than 8 channels ({}), this is not supported by the reference implementation.", LOADER_TRY(m_stream->tell()) - sizeof(QOA::FrameHeader), header.num_channels); dbgln("QOALoader: Warning: QOA frame at {} has more than 8 channels ({}), this is not supported by the reference implementation.", TRY(m_stream->tell()) - sizeof(QOA::FrameHeader), header.num_channels);
if (header.num_channels == 0) if (header.num_channels == 0)
return LoaderError { LoaderError::Category::Format, LOADER_TRY(m_stream->tell()), "QOA frame: Number of channels must be greater than 0" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "QOA frame: Number of channels must be greater than 0" };
if (header.sample_count > QOA::max_frame_samples) if (header.sample_count > QOA::max_frame_samples)
return LoaderError { LoaderError::Category::Format, LOADER_TRY(m_stream->tell()), "QOA frame: Too many samples in frame" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "QOA frame: Too many samples in frame" };
// We weren't given a large enough buffer; signal that we didn't write anything and return. // We weren't given a large enough buffer; signal that we didn't write anything and return.
if (header.sample_count > target.size()) { if (header.sample_count > target.size()) {
target = target.trim(0); target = target.trim(0);
LOADER_TRY(m_stream->seek(-sizeof(QOA::frame_header_size), AK::SeekMode::FromCurrentPosition)); TRY(m_stream->seek(-sizeof(QOA::frame_header_size), AK::SeekMode::FromCurrentPosition));
return {}; return {};
} }
target = target.trim(header.sample_count); target = target.trim(header.sample_count);
auto lms_states = LOADER_TRY(FixedArray<QOA::LMSState>::create(header.num_channels)); auto lms_states = TRY(FixedArray<QOA::LMSState>::create(header.num_channels));
for (size_t channel = 0; channel < header.num_channels; ++channel) { for (size_t channel = 0; channel < header.num_channels; ++channel) {
auto history_packed = LOADER_TRY(m_stream->read_value<BigEndian<u64>>()); auto history_packed = TRY(m_stream->read_value<BigEndian<u64>>());
auto weights_packed = LOADER_TRY(m_stream->read_value<BigEndian<u64>>()); auto weights_packed = TRY(m_stream->read_value<BigEndian<u64>>());
lms_states[channel] = { history_packed, weights_packed }; lms_states[channel] = { history_packed, weights_packed };
} }
// We pre-allocate very large arrays here, but that's the last allocation of the QOA loader! // We pre-allocate very large arrays here, but that's the last allocation of the QOA loader!
// Everything else is just shuffling data around. // Everything else is just shuffling data around.
// (We will also be using all of the arrays in every frame but the last one.) // (We will also be using all of the arrays in every frame but the last one.)
auto channels = LOADER_TRY((FixedArray<Array<i16, QOA::max_frame_samples>>::create(header.num_channels))); auto channels = TRY((FixedArray<Array<i16, QOA::max_frame_samples>>::create(header.num_channels)));
// There's usually (and at maximum) 256 slices per channel, but less at the very end. // There's usually (and at maximum) 256 slices per channel, but less at the very end.
// If the final slice would be partial, we still need to decode it; integer division would tell us that this final slice doesn't exist. // If the final slice would be partial, we still need to decode it; integer division would tell us that this final slice doesn't exist.
@ -105,7 +105,7 @@ MaybeLoaderError QOALoaderPlugin::load_one_frame(Span<Sample>& target, IsFirstFr
m_sample_rate = header.sample_rate; m_sample_rate = header.sample_rate;
} else { } else {
if (m_sample_rate != header.sample_rate) if (m_sample_rate != header.sample_rate)
return LoaderError { LoaderError::Category::Unimplemented, LOADER_TRY(m_stream->tell()), "QOA: Differing sample rate in non-initial frame" }; return LoaderError { LoaderError::Category::Unimplemented, TRY(m_stream->tell()), "QOA: Differing sample rate in non-initial frame" };
if (m_num_channels != header.num_channels) if (m_num_channels != header.num_channels)
m_has_uniform_channel_count = false; m_has_uniform_channel_count = false;
} }
@ -148,17 +148,17 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> QOALoaderPlugin::load_chunks(si
size_t current_loaded_samples = 0; size_t current_loaded_samples = 0;
while (current_loaded_samples < samples_to_read) { while (current_loaded_samples < samples_to_read) {
auto samples = LOADER_TRY(FixedArray<Sample>::create(QOA::max_frame_samples)); auto samples = TRY(FixedArray<Sample>::create(QOA::max_frame_samples));
auto slice_to_load_into = samples.span(); auto slice_to_load_into = samples.span();
TRY(this->load_one_frame(slice_to_load_into, is_first_frame)); TRY(this->load_one_frame(slice_to_load_into, is_first_frame));
is_first_frame = IsFirstFrame::No; is_first_frame = IsFirstFrame::No;
VERIFY(slice_to_load_into.size() <= QOA::max_frame_samples); VERIFY(slice_to_load_into.size() <= QOA::max_frame_samples);
current_loaded_samples += slice_to_load_into.size(); current_loaded_samples += slice_to_load_into.size();
if (slice_to_load_into.size() != samples.size()) { if (slice_to_load_into.size() != samples.size()) {
auto smaller_samples = LOADER_TRY(FixedArray<Sample>::create(slice_to_load_into)); auto smaller_samples = TRY(FixedArray<Sample>::create(slice_to_load_into));
samples.swap(smaller_samples); samples.swap(smaller_samples);
} }
LOADER_TRY(frames.try_append(move(samples))); TRY(frames.try_append(move(samples)));
if (slice_to_load_into.size() != samples.size()) if (slice_to_load_into.size() != samples.size())
break; break;
@ -170,14 +170,14 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> QOALoaderPlugin::load_chunks(si
MaybeLoaderError QOALoaderPlugin::reset() MaybeLoaderError QOALoaderPlugin::reset()
{ {
LOADER_TRY(m_stream->seek(QOA::header_size, AK::SeekMode::SetPosition)); TRY(m_stream->seek(QOA::header_size, AK::SeekMode::SetPosition));
m_loaded_samples = 0; m_loaded_samples = 0;
// Read the first frame, then seek back to the beginning. This is necessary since the first frame contains the sample rate and channel count. // Read the first frame, then seek back to the beginning. This is necessary since the first frame contains the sample rate and channel count.
auto frame_samples = LOADER_TRY(FixedArray<Sample>::create(QOA::max_frame_samples)); auto frame_samples = TRY(FixedArray<Sample>::create(QOA::max_frame_samples));
auto span = frame_samples.span(); auto span = frame_samples.span();
LOADER_TRY(load_one_frame(span, IsFirstFrame::Yes)); TRY(load_one_frame(span, IsFirstFrame::Yes));
LOADER_TRY(m_stream->seek(QOA::header_size, AK::SeekMode::SetPosition)); TRY(m_stream->seek(QOA::header_size, AK::SeekMode::SetPosition));
m_loaded_samples = 0; m_loaded_samples = 0;
return {}; return {};
} }
@ -189,14 +189,14 @@ MaybeLoaderError QOALoaderPlugin::seek(int sample_index)
// A QOA file consists of 8 bytes header followed by a number of usually fixed-size frames. // A QOA file consists of 8 bytes header followed by a number of usually fixed-size frames.
// This fixed bitrate allows us to seek in constant time. // This fixed bitrate allows us to seek in constant time.
if (!m_has_uniform_channel_count) if (!m_has_uniform_channel_count)
return LoaderError { LoaderError::Category::Unimplemented, LOADER_TRY(m_stream->tell()), "QOA with non-uniform channel count is currently not seekable"sv }; return LoaderError { LoaderError::Category::Unimplemented, TRY(m_stream->tell()), "QOA with non-uniform channel count is currently not seekable"sv };
/// FIXME: Change the Loader API to use size_t. /// FIXME: Change the Loader API to use size_t.
VERIFY(sample_index >= 0); VERIFY(sample_index >= 0);
// We seek to the frame "before"; i.e. the frame that contains that sample. // We seek to the frame "before"; i.e. the frame that contains that sample.
auto const frame_of_sample = static_cast<size_t>(AK::floor<double>(static_cast<double>(sample_index) / static_cast<double>(QOA::max_frame_samples))); auto const frame_of_sample = static_cast<size_t>(AK::floor<double>(static_cast<double>(sample_index) / static_cast<double>(QOA::max_frame_samples)));
auto const frame_size = QOA::frame_header_size + m_num_channels * (QOA::lms_state_size + sizeof(QOA::PackedSlice) * QOA::max_slices_per_frame); auto const frame_size = QOA::frame_header_size + m_num_channels * (QOA::lms_state_size + sizeof(QOA::PackedSlice) * QOA::max_slices_per_frame);
auto const byte_index = QOA::header_size + frame_of_sample * frame_size; auto const byte_index = QOA::header_size + frame_of_sample * frame_size;
LOADER_TRY(m_stream->seek(byte_index, AK::SeekMode::SetPosition)); TRY(m_stream->seek(byte_index, AK::SeekMode::SetPosition));
m_loaded_samples = frame_of_sample * QOA::max_frame_samples; m_loaded_samples = frame_of_sample * QOA::max_frame_samples;
return {}; return {};
} }
@ -205,7 +205,7 @@ MaybeLoaderError QOALoaderPlugin::read_one_slice(QOA::LMSState& lms_state, Span<
{ {
VERIFY(samples.size() == QOA::slice_samples); VERIFY(samples.size() == QOA::slice_samples);
auto packed_slice = LOADER_TRY(m_stream->read_value<BigEndian<u64>>()); auto packed_slice = TRY(m_stream->read_value<BigEndian<u64>>());
auto unpacked_slice = unpack_slice(packed_slice); auto unpacked_slice = unpack_slice(packed_slice);
for (size_t i = 0; i < QOA::slice_samples; ++i) { for (size_t i = 0; i < QOA::slice_samples; ++i) {

View file

@ -42,7 +42,7 @@ bool WavLoaderPlugin::sniff(SeekableStream& stream)
ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> WavLoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream) ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> WavLoaderPlugin::create(NonnullOwnPtr<SeekableStream> stream)
{ {
auto loader = make<WavLoaderPlugin>(move(stream)); auto loader = make<WavLoaderPlugin>(move(stream));
LOADER_TRY(loader->parse_header()); TRY(loader->parse_header());
return loader; return loader;
} }
@ -52,12 +52,12 @@ MaybeLoaderError WavLoaderPlugin::read_samples_from_stream(Stream& stream, Sampl
switch (m_num_channels) { switch (m_num_channels) {
case 1: case 1:
for (auto& sample : samples) for (auto& sample : samples)
sample = Sample(LOADER_TRY(read_sample(stream))); sample = Sample(TRY(read_sample(stream)));
break; break;
case 2: case 2:
for (auto& sample : samples) { for (auto& sample : samples) {
auto left_channel_sample = LOADER_TRY(read_sample(stream)); auto left_channel_sample = TRY(read_sample(stream));
auto right_channel_sample = LOADER_TRY(read_sample(stream)); auto right_channel_sample = TRY(read_sample(stream));
sample = Sample(left_channel_sample, right_channel_sample); sample = Sample(left_channel_sample, right_channel_sample);
} }
break; break;
@ -106,7 +106,7 @@ static ErrorOr<double> read_sample(Stream& stream)
LoaderSamples WavLoaderPlugin::samples_from_pcm_data(Bytes const& data, size_t samples_to_read) const LoaderSamples WavLoaderPlugin::samples_from_pcm_data(Bytes const& data, size_t samples_to_read) const
{ {
FixedArray<Sample> samples = LOADER_TRY(FixedArray<Sample>::create(samples_to_read)); FixedArray<Sample> samples = TRY(FixedArray<Sample>::create(samples_to_read));
FixedMemoryStream stream { data }; FixedMemoryStream stream { data };
switch (m_sample_format) { switch (m_sample_format) {
@ -151,8 +151,8 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> WavLoaderPlugin::load_chunks(si
bytes_to_read, m_num_channels, m_sample_rate, bytes_to_read, m_num_channels, m_sample_rate,
pcm_bits_per_sample(m_sample_format), sample_format_name(m_sample_format)); pcm_bits_per_sample(m_sample_format), sample_format_name(m_sample_format));
auto sample_data = LOADER_TRY(ByteBuffer::create_zeroed(bytes_to_read)); auto sample_data = TRY(ByteBuffer::create_zeroed(bytes_to_read));
LOADER_TRY(m_stream->read_until_filled(sample_data.bytes())); TRY(m_stream->read_until_filled(sample_data.bytes()));
// m_loaded_samples should contain the amount of actually loaded samples // m_loaded_samples should contain the amount of actually loaded samples
m_loaded_samples += samples_to_read; m_loaded_samples += samples_to_read;
@ -169,7 +169,7 @@ MaybeLoaderError WavLoaderPlugin::seek(int sample_index)
size_t sample_offset = m_byte_offset_of_data_samples + static_cast<size_t>(sample_index * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8)); size_t sample_offset = m_byte_offset_of_data_samples + static_cast<size_t>(sample_index * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8));
LOADER_TRY(m_stream->seek(sample_offset, SeekMode::SetPosition)); TRY(m_stream->seek(sample_offset, SeekMode::SetPosition));
m_loaded_samples = sample_index; m_loaded_samples = sample_index;
return {}; return {};
@ -178,11 +178,11 @@ MaybeLoaderError WavLoaderPlugin::seek(int sample_index)
// Specification reference: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html // Specification reference: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
MaybeLoaderError WavLoaderPlugin::parse_header() MaybeLoaderError WavLoaderPlugin::parse_header()
{ {
#define CHECK(check, category, msg) \ #define CHECK(check, category, msg) \
do { \ do { \
if (!(check)) { \ if (!(check)) { \
return LoaderError { category, static_cast<size_t>(LOADER_TRY(m_stream->tell())), DeprecatedString::formatted("WAV header: {}", msg) }; \ return LoaderError { category, static_cast<size_t>(TRY(m_stream->tell())), DeprecatedString::formatted("WAV header: {}", msg) }; \
} \ } \
} while (0) } while (0)
auto riff = TRY(m_stream->read_value<RIFF::ChunkID>()); auto riff = TRY(m_stream->read_value<RIFF::ChunkID>());