|
1 | 1 | /* |
2 | 2 | * Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org> |
| 3 | + * Copyright (c) 2025, Gregory Bertilson <gregory@ladybird.org> |
3 | 4 | * |
4 | 5 | * SPDX-License-Identifier: BSD-2-Clause |
5 | 6 | */ |
6 | 7 |
|
7 | | -#include <LibMedia/Audio/Loader.h> |
| 8 | +#include <AK/Time.h> |
| 9 | +#include <LibCore/EventLoop.h> |
| 10 | +#include <LibCore/MappedFile.h> |
| 11 | +#include <LibMedia/DecoderError.h> |
| 12 | +#include <LibMedia/FFmpeg/FFmpegDemuxer.h> |
| 13 | +#include <LibMedia/MutexedDemuxer.h> |
| 14 | +#include <LibMedia/Providers/AudioDataProvider.h> |
8 | 15 | #include <LibTest/TestCase.h> |
9 | 16 |
|
10 | 17 | static void run_test(StringView file_name, int const num_samples, int const channels, u32 const rate) |
11 | 18 | { |
12 | | - constexpr auto format = "ogg"; |
13 | | - constexpr int bits = 32; |
| 19 | + Core::EventLoop loop; |
14 | 20 |
|
15 | | - ByteString in_path = ByteString::formatted("vorbis/{}", file_name); |
| 21 | + ByteString in_path = ByteString::formatted("{}", file_name); |
16 | 22 |
|
17 | | - auto loader = TRY_OR_FAIL(Audio::Loader::create(in_path)); |
| 23 | + auto mapped_file = TRY_OR_FAIL(Core::MappedFile::map(in_path)); |
| 24 | + auto demuxer = TRY_OR_FAIL(Media::FFmpeg::FFmpegDemuxer::from_data(mapped_file->bytes())); |
| 25 | + auto mutexed_demuxer = make_ref_counted<Media::MutexedDemuxer>(demuxer); |
| 26 | + auto track = TRY_OR_FAIL(demuxer->get_preferred_track_for_type(Media::TrackType::Audio)); |
| 27 | + VERIFY(track.has_value()); |
| 28 | + auto provider = TRY_OR_FAIL(Media::AudioDataProvider::try_create(mutexed_demuxer, track.release_value())); |
18 | 29 |
|
19 | | - EXPECT_EQ(loader->format_name(), format); |
20 | | - EXPECT_EQ(loader->sample_rate(), rate); |
21 | | - EXPECT_EQ(loader->num_channels(), channels); |
22 | | - EXPECT_EQ(loader->bits_per_sample(), bits); |
23 | | - EXPECT_EQ(loader->total_samples(), num_samples); |
| 30 | + auto reached_end = false; |
| 31 | + provider->set_error_handler([&](Media::DecoderError&& error) { |
| 32 | + if (error.category() == Media::DecoderErrorCategory::EndOfStream) { |
| 33 | + reached_end = true; |
| 34 | + return; |
| 35 | + } |
| 36 | + FAIL("An error occurred while decoding."); |
| 37 | + }); |
| 38 | + |
| 39 | + auto time_limit = AK::Duration::from_seconds(1); |
| 40 | + auto start_time = MonotonicTime::now_coarse(); |
| 41 | + |
| 42 | + i64 sample_count = 0; |
| 43 | + |
| 44 | + while (true) { |
| 45 | + auto block = provider->retrieve_block(); |
| 46 | + if (block.is_empty()) { |
| 47 | + if (reached_end) |
| 48 | + break; |
| 49 | + } else { |
| 50 | + EXPECT_EQ(block.sample_rate(), rate); |
| 51 | + EXPECT_EQ(block.channel_count(), channels); |
| 52 | + |
| 53 | + sample_count += block.sample_count(); |
| 54 | + } |
| 55 | + |
| 56 | + if (MonotonicTime::now_coarse() - start_time >= time_limit) { |
| 57 | + FAIL("Decoding timed out."); |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + loop.pump(Core::EventLoop::WaitMode::PollForEvents); |
| 62 | + } |
| 63 | + |
| 64 | + VERIFY(reached_end); |
| 65 | + EXPECT_EQ(sample_count, num_samples); |
24 | 66 | } |
25 | 67 |
|
26 | 68 | TEST_CASE(44_1Khz_stereo) |
27 | 69 | { |
28 | | - run_test("44_1Khz_stereo.ogg"sv, 352800, 2, 44100); |
| 70 | + // NOTE: 96 samples are marked to be discarded, but AudioDataProvider currently is not aware of this. |
| 71 | + run_test("vorbis/44_1Khz_stereo.ogg"sv, 352800 + 96, 2, 44100); |
29 | 72 | } |
0 commit comments