1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 18:57:35 +00:00

LibAudio: Create MP3 seek table first and then seek sample 0 to play

The seek table must locate the first MP3 frame in the file, so it makes
sense to locate the samples for the sample table first, then that
information to seek to the first frame.
This commit is contained in:
Zaggy1024 2023-08-25 19:37:39 -05:00 committed by Tim Flynn
parent 49be09e5b2
commit 5b8895fff0

View file

@ -83,10 +83,11 @@ ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> MP3LoaderPlugin::create(Nonnul
MaybeLoaderError MP3LoaderPlugin::initialize()
{
TRY(skip_id3(*m_stream));
m_bitstream = TRY(try_make<BigEndianInputBitStream>(MaybeOwned<Stream>(*m_stream)));
TRY(synchronize());
TRY(build_seek_table());
TRY(seek(0));
TRY(synchronize());
auto header = TRY(read_header());
if (header.id != 1 || header.layer != 3)
return LoaderError { LoaderError::Category::Format, "Only MPEG-1 layer 3 supported." };
@ -95,7 +96,6 @@ MaybeLoaderError MP3LoaderPlugin::initialize()
m_num_channels = header.channel_count();
m_loaded_samples = 0;
TRY(build_seek_table());
TRY(seek(0));
return {};
@ -170,12 +170,14 @@ ErrorOr<Vector<FixedArray<Sample>>, LoaderError> MP3LoaderPlugin::load_chunks(si
MaybeLoaderError MP3LoaderPlugin::build_seek_table()
{
VERIFY(MUST(m_stream->tell()) == 0);
TRY(skip_id3(*m_stream));
m_bitstream->align_to_byte_boundary();
int sample_count = 0;
size_t frame_count = 0;
m_seek_table = {};
m_bitstream->align_to_byte_boundary();
while (!synchronize().is_error()) {
auto const frame_pos = -2 + TRY(m_stream->seek(0, SeekMode::FromCurrentPosition));