LibAudio: Replace DeprecatedFlyString with FlyString

This commit is contained in:
FujiBookPro 2024-05-27 15:27:01 -04:00 committed by Andrew Kaster
parent 3b05c81070
commit 728f42f8f5
6 changed files with 62 additions and 61 deletions

View file

@ -63,11 +63,11 @@ 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, TRY(m_stream->tell()), ByteString::formatted("FLAC header: {}", msg) }; \ return LoaderError { category, TRY(m_stream->tell()), TRY(String::formatted("FLAC header: {}", msg)) }; \
} \ } \
} while (0) } while (0)
// Magic number // Magic number
@ -165,19 +165,19 @@ MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block)
auto const mime_string_length = 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, 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"_fly_string };
// "The MIME type string, in printable ASCII characters 0x20-0x7E." // "The MIME type string, in printable ASCII characters 0x20-0x7E."
picture.mime_string = 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, 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"_fly_string };
} }
auto const description_string_length = 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, TRY(m_stream->tell()), "Picture description exceeds available data" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Picture description exceeds available data"_fly_string };
picture.description_string = TRY(String::from_stream(memory_stream, description_string_length)); picture.description_string = TRY(String::from_stream(memory_stream, description_string_length));
@ -190,7 +190,7 @@ MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block)
auto const picture_size = 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"_fly_string };
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) };
@ -305,7 +305,7 @@ MaybeLoaderError FlacLoaderPlugin::seek(int int_sample_index)
dbgln_if(AFLACLOADER_DEBUG, "Seeking to seektable: sample index {}, byte offset {}", target_seekpoint.sample_index, target_seekpoint.byte_offset); dbgln_if(AFLACLOADER_DEBUG, "Seeking to seektable: sample index {}, byte offset {}", target_seekpoint.sample_index, target_seekpoint.byte_offset);
auto position = target_seekpoint.byte_offset + m_data_start_location; auto position = target_seekpoint.byte_offset + m_data_start_location;
if (m_stream->seek(static_cast<i64>(position), SeekMode::SetPosition).is_error()) if (m_stream->seek(static_cast<i64>(position), SeekMode::SetPosition).is_error())
return LoaderError { LoaderError::Category::IO, m_loaded_samples, ByteString::formatted("Invalid seek position {}", position) }; return LoaderError { LoaderError::Category::IO, m_loaded_samples, TRY(String::formatted("Invalid seek position {}", position)) };
m_loaded_samples = target_seekpoint.sample_index; m_loaded_samples = target_seekpoint.sample_index;
} }
} }
@ -367,11 +367,11 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> FlacLoaderPlugin::load_chunks(s
// 11.21. FRAME // 11.21. FRAME
LoaderSamples FlacLoaderPlugin::next_frame() LoaderSamples FlacLoaderPlugin::next_frame()
{ {
#define FLAC_VERIFY(check, category, msg) \ #define FLAC_VERIFY(check, category, msg) \
do { \ do { \
if (!(check)) { \ if (!(check)) { \
return LoaderError { category, static_cast<size_t>(m_current_sample_or_frame), ByteString::formatted("FLAC header: {}", msg) }; \ return LoaderError { category, static_cast<size_t>(m_current_sample_or_frame), TRY(String::formatted("FLAC header: {}", msg)) }; \
} \ } \
} while (0) } while (0)
auto frame_byte_index = TRY(m_stream->tell()); auto frame_byte_index = TRY(m_stream->tell());
@ -538,7 +538,7 @@ ErrorOr<u32, LoaderError> FlacLoaderPlugin::convert_sample_count_code(u8 sample_
// single codes // single codes
switch (sample_count_code) { switch (sample_count_code) {
case 0: case 0:
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved block size" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved block size"_fly_string };
case 1: case 1:
return 192; return 192;
case 6: case 6:
@ -587,7 +587,7 @@ ErrorOr<u32, LoaderError> FlacLoaderPlugin::convert_sample_rate_code(u8 sample_r
case 14: case 14:
return FLAC_SAMPLERATE_AT_END_OF_HEADER_16X10; return FLAC_SAMPLERATE_AT_END_OF_HEADER_16X10;
default: default:
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Invalid sample rate code" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Invalid sample rate code"_fly_string };
} }
} }
@ -602,7 +602,7 @@ ErrorOr<u8, LoaderError> FlacLoaderPlugin::convert_bit_depth_code(u8 bit_depth_c
case 2: case 2:
return 12; return 12;
case 3: case 3:
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved sample size" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved sample size"_fly_string };
case 4: case 4:
return 16; return 16;
case 5: case 5:
@ -612,7 +612,7 @@ ErrorOr<u8, LoaderError> FlacLoaderPlugin::convert_bit_depth_code(u8 bit_depth_c
case 7: case 7:
return 32; return 32;
default: default:
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), ByteString::formatted("Unsupported sample size {}", bit_depth_code) }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), TRY(String::formatted("Unsupported sample size {}", bit_depth_code)) };
} }
} }
@ -649,12 +649,12 @@ ErrorOr<FlacSubframeHeader, LoaderError> FlacLoaderPlugin::next_subframe_header(
// zero-bit padding // zero-bit padding
if (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"_fly_string };
// 11.25.1. SUBFRAME TYPE // 11.25.1. SUBFRAME TYPE
u8 subframe_code = 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"_fly_string };
FlacSubframeType subframe_type; FlacSubframeType subframe_type;
u8 order = 0; u8 order = 0;
@ -722,7 +722,7 @@ ErrorOr<void, LoaderError> FlacLoaderPlugin::parse_subframe(Vector<i64>& samples
break; break;
} }
default: default:
return LoaderError { LoaderError::Category::Unimplemented, static_cast<size_t>(m_current_sample_or_frame), "Unhandled FLAC subframe type" }; return LoaderError { LoaderError::Category::Unimplemented, static_cast<size_t>(m_current_sample_or_frame), "Unhandled FLAC subframe type"_fly_string };
} }
for (size_t i = 0; i < samples.size(); ++i) { for (size_t i = 0; i < samples.size(); ++i) {
@ -750,7 +750,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_verbatim(FlacSubframe
return LoaderError { return LoaderError {
LoaderError::Category::Format, LoaderError::Category::Format,
TRY(m_stream->tell()), TRY(m_stream->tell()),
"Effective verbatim bits per sample are zero"sv, "Effective verbatim bits per sample are zero"_fly_string,
}; };
} }
for (size_t i = 0; i < m_current_frame->sample_count; ++i) { for (size_t i = 0; i < m_current_frame->sample_count; ++i) {
@ -768,7 +768,7 @@ ErrorOr<void, LoaderError> FlacLoaderPlugin::decode_custom_lpc(Vector<i64>& deco
{ {
// LPC must provide at least as many samples as its order. // LPC must provide at least as many samples as its order.
if (subframe.order > m_current_frame->sample_count) if (subframe.order > m_current_frame->sample_count)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too small frame for LPC order" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too small frame for LPC order"_fly_string };
decoded.ensure_capacity(m_current_frame->sample_count); decoded.ensure_capacity(m_current_frame->sample_count);
@ -776,7 +776,7 @@ ErrorOr<void, LoaderError> FlacLoaderPlugin::decode_custom_lpc(Vector<i64>& deco
return LoaderError { return LoaderError {
LoaderError::Category::Format, LoaderError::Category::Format,
TRY(m_stream->tell()), TRY(m_stream->tell()),
"Effective verbatim bits per sample are zero"sv, "Effective verbatim bits per sample are zero"_fly_string,
}; };
} }
// warm-up samples // warm-up samples
@ -789,7 +789,7 @@ ErrorOr<void, LoaderError> FlacLoaderPlugin::decode_custom_lpc(Vector<i64>& deco
// precision of the coefficients // precision of the coefficients
u8 lpc_precision = 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"_fly_string };
lpc_precision += 1; lpc_precision += 1;
// shift needed on the data (signed!) // shift needed on the data (signed!)
@ -832,7 +832,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_fixed_lpc(FlacSubfram
{ {
// LPC must provide at least as many samples as its order. // LPC must provide at least as many samples as its order.
if (subframe.order > m_current_frame->sample_count) if (subframe.order > m_current_frame->sample_count)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too small frame for LPC order" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too small frame for LPC order"_fly_string };
Vector<i64> decoded; Vector<i64> decoded;
decoded.ensure_capacity(m_current_frame->sample_count); decoded.ensure_capacity(m_current_frame->sample_count);
@ -841,7 +841,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_fixed_lpc(FlacSubfram
return LoaderError { return LoaderError {
LoaderError::Category::Format, LoaderError::Category::Format,
TRY(m_stream->tell()), TRY(m_stream->tell()),
"Effective verbatim bits per sample are zero"sv, "Effective verbatim bits per sample are zero"_fly_string,
}; };
} }
// warm-up samples // warm-up samples
@ -900,7 +900,7 @@ ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_fixed_lpc(FlacSubfram
decoded[i] += 4 * decoded[i - 1] - 6 * decoded[i - 2] + 4 * decoded[i - 3] - decoded[i - 4]; decoded[i] += 4 * decoded[i - 1] - 6 * decoded[i - 2] + 4 * decoded[i - 3] - decoded[i - 4];
break; break;
default: default:
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), ByteString::formatted("Unrecognized predictor order {}", subframe.order) }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), TRY(String::formatted("Unrecognized predictor order {}", subframe.order)) };
} }
return decoded; return decoded;
} }
@ -917,11 +917,11 @@ MaybeLoaderError FlacLoaderPlugin::decode_residual(Vector<i64>& decoded, FlacSub
dbgln_if(AFLACLOADER_DEBUG, " {}-bit Rice partitions, {} total (order {})", residual_mode == FlacResidualMode::Rice4Bit ? "4"sv : "5"sv, partitions, partition_order); dbgln_if(AFLACLOADER_DEBUG, " {}-bit Rice partitions, {} total (order {})", residual_mode == FlacResidualMode::Rice4Bit ? "4"sv : "5"sv, partitions, partition_order);
if (partitions > m_current_frame->sample_count) if (partitions > m_current_frame->sample_count)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too many Rice partitions, each partition must contain at least one sample" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Too many Rice partitions, each partition must contain at least one sample"_fly_string };
// “The partition order MUST be such that the block size is evenly divisible by the number of partitions.” // “The partition order MUST be such that the block size is evenly divisible by the number of partitions.”
// FIXME: Check “The partition order also MUST be such that the (block size >> partition order) is larger than the predictor order.” // FIXME: Check “The partition order also MUST be such that the (block size >> partition order) is larger than the predictor order.”
if (m_current_frame->sample_count % partitions != 0) if (m_current_frame->sample_count % partitions != 0)
return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Block size is not evenly divisible by number of partitions" }; return LoaderError { LoaderError::Category::Format, TRY(m_stream->tell()), "Block size is not evenly divisible by number of partitions"_fly_string };
if (residual_mode == FlacResidualMode::Rice4Bit) { if (residual_mode == FlacResidualMode::Rice4Bit) {
// 11.30.2. RESIDUAL_CODING_METHOD_PARTITIONED_EXP_GOLOMB // 11.30.2. RESIDUAL_CODING_METHOD_PARTITIONED_EXP_GOLOMB
@ -940,7 +940,7 @@ MaybeLoaderError FlacLoaderPlugin::decode_residual(Vector<i64>& decoded, FlacSub
decoded.extend(move(rice_partition)); decoded.extend(move(rice_partition));
} }
} else } else
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved residual coding method" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "Reserved residual coding method"_fly_string };
return {}; return {};
} }
@ -959,7 +959,7 @@ ALWAYS_INLINE ErrorOr<Vector<i64>, LoaderError> FlacLoaderPlugin::decode_rice_pa
residual_sample_count = m_current_frame->sample_count / partitions; residual_sample_count = m_current_frame->sample_count / partitions;
if (partition_index == 0) { if (partition_index == 0) {
if (subframe.order > residual_sample_count) if (subframe.order > residual_sample_count)
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "First Rice partition must advertise more residuals than LPC order" }; return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), "First Rice partition must advertise more residuals than LPC order"_fly_string };
residual_sample_count -= subframe.order; residual_sample_count -= subframe.order;
} }

View file

@ -66,7 +66,7 @@ ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> Loader::create_plugin(NonnullO
TRY(stream->seek(0, SeekMode::SetPosition)); TRY(stream->seek(0, SeekMode::SetPosition));
} }
return LoaderError { "No loader plugin available" }; return LoaderError { "No loader plugin available"_fly_string };
} }
LoaderSamples Loader::get_more_samples(size_t samples_to_read_from_input) LoaderSamples Loader::get_more_samples(size_t samples_to_read_from_input)

View file

@ -8,6 +8,7 @@
#include <AK/DeprecatedFlyString.h> #include <AK/DeprecatedFlyString.h>
#include <AK/Error.h> #include <AK/Error.h>
#include <AK/FlyString.h>
#include <errno.h> #include <errno.h>
namespace Audio { namespace Audio {
@ -28,20 +29,20 @@ struct LoaderError {
Category category { Category::Unknown }; Category category { Category::Unknown };
// Binary index: where in the file the error occurred. // Binary index: where in the file the error occurred.
size_t index { 0 }; size_t index { 0 };
DeprecatedFlyString description { ByteString::empty() }; FlyString description { ""_fly_string };
constexpr LoaderError() = default; constexpr LoaderError() = default;
LoaderError(Category category, size_t index, DeprecatedFlyString description) LoaderError(Category category, size_t index, FlyString description)
: category(category) : category(category)
, index(index) , index(index)
, description(move(description)) , description(move(description))
{ {
} }
LoaderError(DeprecatedFlyString description) LoaderError(FlyString description)
: description(move(description)) : description(move(description))
{ {
} }
LoaderError(Category category, DeprecatedFlyString description) LoaderError(Category category, FlyString description)
: category(category) : category(category)
, description(move(description)) , description(move(description))
{ {
@ -54,11 +55,11 @@ struct LoaderError {
{ {
if (error.is_errno()) { if (error.is_errno()) {
auto code = error.code(); auto code = error.code();
description = ByteString::formatted("{} ({})", strerror(code), code); description = String::formatted("{} ({})", strerror(code), code).release_value_but_fixme_should_propagate_errors();
if (code == EBADF || code == EBUSY || code == EEXIST || code == EIO || code == EISDIR || code == ENOENT || code == ENOMEM || code == EPIPE) if (code == EBADF || code == EBUSY || code == EEXIST || code == EIO || code == EISDIR || code == ENOENT || code == ENOMEM || code == EPIPE)
category = Category::IO; category = Category::IO;
} else { } else {
description = error.string_literal(); description = FlyString::from_utf8(error.string_literal()).release_value_but_fixme_should_propagate_errors();
} }
} }
}; };

View file

@ -166,19 +166,19 @@ ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::read_header(SeekableStream& s
{ {
auto bitstream = BigEndianInputBitStream(MaybeOwned<Stream>(stream)); auto bitstream = BigEndianInputBitStream(MaybeOwned<Stream>(stream));
if (TRY(bitstream.read_bits(4)) != 0xF) if (TRY(bitstream.read_bits(4)) != 0xF)
return LoaderError { LoaderError::Category::Format, sample_index, "Frame header did not start with sync code." }; return LoaderError { LoaderError::Category::Format, sample_index, "Frame header did not start with sync code."_fly_string };
MP3::Header header; MP3::Header header;
header.id = TRY(bitstream.read_bit()); header.id = TRY(bitstream.read_bit());
header.layer = MP3::Tables::LayerNumberLookup[TRY(bitstream.read_bits(2))]; header.layer = MP3::Tables::LayerNumberLookup[TRY(bitstream.read_bits(2))];
if (header.layer <= 0) if (header.layer <= 0)
return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid layer number." }; return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid layer number."_fly_string };
header.protection_bit = TRY(bitstream.read_bit()); header.protection_bit = TRY(bitstream.read_bit());
header.bitrate = MP3::Tables::BitratesPerLayerLookup[header.layer - 1][TRY(bitstream.read_bits(4))]; header.bitrate = MP3::Tables::BitratesPerLayerLookup[header.layer - 1][TRY(bitstream.read_bits(4))];
if (header.bitrate <= 0) if (header.bitrate <= 0)
return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid bitrate." }; return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid bitrate."_fly_string };
header.samplerate = MP3::Tables::SampleratesLookup[TRY(bitstream.read_bits(2))]; header.samplerate = MP3::Tables::SampleratesLookup[TRY(bitstream.read_bits(2))];
if (header.samplerate <= 0) if (header.samplerate <= 0)
return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid samplerate." }; return LoaderError { LoaderError::Category::Format, sample_index, "Frame header contains invalid samplerate."_fly_string };
header.padding_bit = TRY(bitstream.read_bit()); header.padding_bit = TRY(bitstream.read_bit());
header.private_bit = TRY(bitstream.read_bit()); header.private_bit = TRY(bitstream.read_bit());
header.mode = static_cast<MP3::Mode>(TRY(bitstream.read_bits(2))); header.mode = static_cast<MP3::Mode>(TRY(bitstream.read_bits(2)));
@ -221,7 +221,7 @@ ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::synchronize_and_read_header(S
} }
return header_result.value(); return header_result.value();
} }
return LoaderError { LoaderError::Category::Format, sample_index, "Failed to synchronize." }; return LoaderError { LoaderError::Category::Format, sample_index, "Failed to synchronize."_fly_string };
} }
ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::synchronize_and_read_header() ErrorOr<MP3::Header, LoaderError> MP3LoaderPlugin::synchronize_and_read_header()
@ -242,7 +242,7 @@ ErrorOr<MP3::MP3Frame, LoaderError> MP3LoaderPlugin::read_frame_data(MP3::Header
auto maybe_buffer = ByteBuffer::create_uninitialized(header.slot_count); auto maybe_buffer = ByteBuffer::create_uninitialized(header.slot_count);
if (maybe_buffer.is_error()) if (maybe_buffer.is_error())
return LoaderError { LoaderError::Category::IO, m_loaded_samples, "Out of memory" }; return LoaderError { LoaderError::Category::IO, m_loaded_samples, "Out of memory"_fly_string };
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();
@ -539,7 +539,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
} }
if (!tree || tree->nodes.is_empty()) { if (!tree || tree->nodes.is_empty()) {
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame references invalid huffman table." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame references invalid huffman table."_fly_string };
} }
// Assumption: There's enough bits to read. 32 is just a placeholder for "unlimited". // Assumption: There's enough bits to read. 32 is just a placeholder for "unlimited".
@ -547,7 +547,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
auto const entry = MP3::Tables::Huffman::huffman_decode(reservoir, tree->nodes, 32); auto const entry = MP3::Tables::Huffman::huffman_decode(reservoir, tree->nodes, 32);
granule_bits_read += entry.bits_read; granule_bits_read += entry.bits_read;
if (!entry.code.has_value()) if (!entry.code.has_value())
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame contains invalid huffman data." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame contains invalid huffman data."_fly_string };
int x = entry.code->symbol.x; int x = entry.code->symbol.x;
int y = entry.code->symbol.y; int y = entry.code->symbol.y;
@ -585,7 +585,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
auto const entry = MP3::Tables::Huffman::huffman_decode(reservoir, count1table, granule.part_2_3_length - granule_bits_read); auto const entry = MP3::Tables::Huffman::huffman_decode(reservoir, count1table, granule.part_2_3_length - granule_bits_read);
granule_bits_read += entry.bits_read; granule_bits_read += entry.bits_read;
if (!entry.code.has_value()) if (!entry.code.has_value())
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame contains invalid huffman data." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Frame contains invalid huffman data."_fly_string };
int v = entry.code->symbol.v; int v = entry.code->symbol.v;
if (v != 0) { if (v != 0) {
if (granule_bits_read >= granule.part_2_3_length) if (granule_bits_read >= granule.part_2_3_length)
@ -628,7 +628,7 @@ MaybeLoaderError MP3LoaderPlugin::read_huffman_data(MP3::MP3Frame& frame, BigEnd
} }
if (granule_bits_read > granule.part_2_3_length) { if (granule_bits_read > granule.part_2_3_length) {
return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Read too many bits from bit reservoir." }; return LoaderError { LoaderError::Category::Format, m_loaded_samples, "Read too many bits from bit reservoir."_fly_string };
} }
// 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

View file

@ -48,7 +48,7 @@ MaybeLoaderError QOALoaderPlugin::parse_header()
{ {
u32 header_magic = 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'"_fly_string };
m_total_samples = TRY(m_stream->read_value<BigEndian<u32>>()); m_total_samples = TRY(m_stream->read_value<BigEndian<u32>>());
@ -62,9 +62,9 @@ MaybeLoaderError QOALoaderPlugin::load_one_frame(Span<Sample>& target, IsFirstFr
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.", 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, 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"_fly_string };
if (header.sample_count > QOA::max_frame_samples) if (header.sample_count > QOA::max_frame_samples)
return LoaderError { LoaderError::Category::Format, 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"_fly_string };
// 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()) {
@ -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, 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"_fly_string };
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;
} }
@ -189,7 +189,7 @@ 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, 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"_fly_string };
/// 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.

View file

@ -165,7 +165,7 @@ MaybeLoaderError WavLoaderPlugin::seek(int sample_index)
{ {
dbgln_if(AWAVLOADER_DEBUG, "seek sample_index {}", sample_index); dbgln_if(AWAVLOADER_DEBUG, "seek sample_index {}", sample_index);
if (sample_index < 0 || sample_index >= static_cast<int>(m_total_samples)) if (sample_index < 0 || sample_index >= static_cast<int>(m_total_samples))
return LoaderError { LoaderError::Category::Internal, m_loaded_samples, "Seek outside the sample range" }; return LoaderError { LoaderError::Category::Internal, m_loaded_samples, "Seek outside the sample range"_fly_string };
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));
@ -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>(TRY(m_stream->tell())), ByteString::formatted("WAV header: {}", msg) }; \ return LoaderError { category, static_cast<size_t>(TRY(m_stream->tell())), TRY(String::formatted("WAV header: {}", msg)) }; \
} \ } \
} while (0) } while (0)
auto file_header = TRY(m_stream->read_value<RIFF::FileHeader>()); auto file_header = TRY(m_stream->read_value<RIFF::FileHeader>());