mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-24 11:35:13 +00:00
LibAudio: Replace DeprecatedFlyString with FlyString
This commit is contained in:
parent
3b05c81070
commit
728f42f8f5
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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>());
|
||||||
|
|
Loading…
Reference in a new issue