mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:47:45 +00:00
LibAudio: Use specified bit depth directly
We report a rounded up PCM sample format to the outside, but use the exact bit depth as specified in header and frames. This makes the three FLAC spec tests with a a bit depth of 20 pass.
This commit is contained in:
parent
a2d13c47bd
commit
b2a018ee59
3 changed files with 36 additions and 29 deletions
|
@ -68,7 +68,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
|
||||||
#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_data_start_location), DeprecatedString::formatted("FLAC header: {}", msg) }; \
|
return LoaderError { category, LOADER_TRY(m_stream->tell()), DeprecatedString::formatted("FLAC header: {}", msg) }; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -94,18 +94,18 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
|
||||||
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 = LOADER_TRY(streaminfo_data.read_bits<u8>(3)) + 1; // 0 = one channel
|
||||||
|
|
||||||
u8 bits_per_sample = LOADER_TRY(streaminfo_data.read_bits<u8>(5)) + 1;
|
m_bits_per_sample = LOADER_TRY(streaminfo_data.read_bits<u8>(5)) + 1;
|
||||||
if (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;
|
||||||
} else if (bits_per_sample == 16) {
|
} else if (m_bits_per_sample <= 16) {
|
||||||
m_sample_format = PcmSampleFormat::Int16;
|
m_sample_format = PcmSampleFormat::Int16;
|
||||||
} else if (bits_per_sample == 24) {
|
} else if (m_bits_per_sample <= 24) {
|
||||||
m_sample_format = PcmSampleFormat::Int24;
|
m_sample_format = PcmSampleFormat::Int24;
|
||||||
} else if (bits_per_sample == 32) {
|
} else if (m_bits_per_sample <= 32) {
|
||||||
m_sample_format = PcmSampleFormat::Int32;
|
m_sample_format = PcmSampleFormat::Int32;
|
||||||
} else {
|
} else {
|
||||||
FLAC_VERIFY(false, LoaderError::Category::Format, "Sample bit depth invalid");
|
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 = LOADER_TRY(streaminfo_data.read_bits<u64>(36));
|
||||||
|
@ -387,7 +387,7 @@ LoaderSamples FlacLoaderPlugin::next_frame()
|
||||||
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;
|
||||||
|
|
||||||
PcmSampleFormat bit_depth = TRY(convert_bit_depth_code(LOADER_TRY(bit_stream.read_bits<u8>(3))));
|
u8 bit_depth = TRY(convert_bit_depth_code(LOADER_TRY(bit_stream.read_bits<u8>(3))));
|
||||||
|
|
||||||
reserved_bit = LOADER_TRY(bit_stream.read_bit());
|
reserved_bit = LOADER_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");
|
||||||
|
@ -417,7 +417,7 @@ LoaderSamples FlacLoaderPlugin::next_frame()
|
||||||
// TODO: check header checksum, see above
|
// TODO: check header checksum, see above
|
||||||
[[maybe_unused]] u8 checksum = LOADER_TRY(bit_stream.read_bits<u8>(8));
|
[[maybe_unused]] u8 checksum = LOADER_TRY(bit_stream.read_bits<u8>(8));
|
||||||
|
|
||||||
dbgln_if(AFLACLOADER_DEBUG, "Frame: {} samples, {}bit {}Hz, channeltype {:x}, {} number {}, header checksum {}", sample_count, pcm_bits_per_sample(bit_depth), frame_sample_rate, channel_type_num, blocking_strategy ? "sample" : "frame", m_current_sample_or_frame, checksum);
|
dbgln_if(AFLACLOADER_DEBUG, "Frame: {} samples, {}bit {}Hz, channeltype {:x}, {} number {}, header checksum {}", sample_count, bit_depth, frame_sample_rate, channel_type_num, blocking_strategy ? "sample" : "frame", m_current_sample_or_frame, checksum);
|
||||||
|
|
||||||
m_current_frame = FlacFrameHeader {
|
m_current_frame = FlacFrameHeader {
|
||||||
sample_count,
|
sample_count,
|
||||||
|
@ -445,8 +445,8 @@ LoaderSamples FlacLoaderPlugin::next_frame()
|
||||||
[[maybe_unused]] u16 footer_checksum = LOADER_TRY(bit_stream.read_bits<u16>(16));
|
[[maybe_unused]] u16 footer_checksum = LOADER_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 << (pcm_bits_per_sample(m_current_frame->bit_depth) - 1));
|
float sample_rescale = 1 / static_cast<float>(1 << (m_current_frame->bit_depth - 1));
|
||||||
dbgln_if(AFLACLOADER_DEBUG, "Sample rescaled from {} bits: factor {:.1f}", pcm_bits_per_sample(m_current_frame->bit_depth), sample_rescale);
|
dbgln_if(AFLACLOADER_DEBUG, "Sample rescaled from {} bits: factor {:.8f}", m_current_frame->bit_depth, sample_rescale);
|
||||||
|
|
||||||
FixedArray<Sample> samples = TRY(FixedArray<Sample>::create(m_current_frame->sample_count));
|
FixedArray<Sample> samples = TRY(FixedArray<Sample>::create(m_current_frame->sample_count));
|
||||||
|
|
||||||
|
@ -559,20 +559,25 @@ ErrorOr<u32, LoaderError> FlacLoaderPlugin::convert_sample_rate_code(u8 sample_r
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.22.6. SAMPLE SIZE
|
// 11.22.6. SAMPLE SIZE
|
||||||
ErrorOr<PcmSampleFormat, LoaderError> FlacLoaderPlugin::convert_bit_depth_code(u8 bit_depth_code)
|
ErrorOr<u8, LoaderError> FlacLoaderPlugin::convert_bit_depth_code(u8 bit_depth_code)
|
||||||
{
|
{
|
||||||
switch (bit_depth_code) {
|
switch (bit_depth_code) {
|
||||||
case 0:
|
case 0:
|
||||||
return m_sample_format;
|
return m_bits_per_sample;
|
||||||
case 1:
|
case 1:
|
||||||
return PcmSampleFormat::Uint8;
|
return 8;
|
||||||
case 4:
|
case 2:
|
||||||
return PcmSampleFormat::Int16;
|
return 12;
|
||||||
case 6:
|
|
||||||
return PcmSampleFormat::Int24;
|
|
||||||
case 3:
|
case 3:
|
||||||
case 7:
|
|
||||||
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" };
|
||||||
|
case 4:
|
||||||
|
return 16;
|
||||||
|
case 5:
|
||||||
|
return 20;
|
||||||
|
case 6:
|
||||||
|
return 24;
|
||||||
|
case 7:
|
||||||
|
return 32;
|
||||||
default:
|
default:
|
||||||
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), DeprecatedString::formatted("Unsupported sample size {}", bit_depth_code) };
|
return LoaderError { LoaderError::Category::Format, static_cast<size_t>(m_current_sample_or_frame), DeprecatedString::formatted("Unsupported sample size {}", bit_depth_code) };
|
||||||
}
|
}
|
||||||
|
@ -589,7 +594,7 @@ u8 frame_channel_type_to_channel_count(FlacFrameChannelType channel_type)
|
||||||
// 11.25. SUBFRAME_HEADER
|
// 11.25. SUBFRAME_HEADER
|
||||||
ErrorOr<FlacSubframeHeader, LoaderError> FlacLoaderPlugin::next_subframe_header(BigEndianInputBitStream& bit_stream, u8 channel_index)
|
ErrorOr<FlacSubframeHeader, LoaderError> FlacLoaderPlugin::next_subframe_header(BigEndianInputBitStream& bit_stream, u8 channel_index)
|
||||||
{
|
{
|
||||||
u8 bits_per_sample = static_cast<u16>(pcm_bits_per_sample(m_current_frame->bit_depth));
|
u8 bits_per_sample = m_current_frame->bit_depth;
|
||||||
|
|
||||||
// For inter-channel correlation, the side channel needs an extra bit for its samples
|
// For inter-channel correlation, the side channel needs an extra bit for its samples
|
||||||
switch (m_current_frame->channels) {
|
switch (m_current_frame->channels) {
|
||||||
|
|
|
@ -85,14 +85,16 @@ private:
|
||||||
// Converters for special coding used in frame headers
|
// Converters for special coding used in frame headers
|
||||||
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_count_code(u8 sample_count_code);
|
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_count_code(u8 sample_count_code);
|
||||||
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_rate_code(u8 sample_rate_code);
|
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_rate_code(u8 sample_rate_code);
|
||||||
ALWAYS_INLINE ErrorOr<PcmSampleFormat, LoaderError> convert_bit_depth_code(u8 bit_depth_code);
|
ALWAYS_INLINE ErrorOr<u8, LoaderError> convert_bit_depth_code(u8 bit_depth_code);
|
||||||
|
|
||||||
bool should_insert_seekpoint_at(u64 sample_index) const;
|
bool should_insert_seekpoint_at(u64 sample_index) const;
|
||||||
|
|
||||||
// Data obtained directly from the FLAC metadata: many values have specific bit counts
|
// Data obtained directly from the FLAC metadata: many values have specific bit counts
|
||||||
u32 m_sample_rate { 0 }; // 20 bit
|
u32 m_sample_rate { 0 }; // 20 bit
|
||||||
u8 m_num_channels { 0 }; // 3 bit
|
u8 m_num_channels { 0 }; // 3 bit
|
||||||
PcmSampleFormat m_sample_format; // 5 bits for the integer bit depth
|
u8 m_bits_per_sample { 0 }; // 5 bits for the integer bit depth
|
||||||
|
// Externally visible format; the smallest integer format that's larger than the precise bit depth.
|
||||||
|
PcmSampleFormat m_sample_format;
|
||||||
// Blocks are units of decoded audio data
|
// Blocks are units of decoded audio data
|
||||||
u16 m_min_block_size { 0 };
|
u16 m_min_block_size { 0 };
|
||||||
u16 m_max_block_size { 0 };
|
u16 m_max_block_size { 0 };
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct FlacFrameHeader {
|
||||||
u32 sample_count;
|
u32 sample_count;
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
FlacFrameChannelType channels;
|
FlacFrameChannelType channels;
|
||||||
PcmSampleFormat bit_depth;
|
u8 bit_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 11.25. SUBFRAME_HEADER
|
// 11.25. SUBFRAME_HEADER
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue