diff --git a/Tests/LibAudio/CMakeLists.txt b/Tests/LibAudio/CMakeLists.txt index 38ddf795d8..ae8d4a2910 100644 --- a/Tests/LibAudio/CMakeLists.txt +++ b/Tests/LibAudio/CMakeLists.txt @@ -1,10 +1,13 @@ set(TEST_SOURCES + TestWav.cpp TestFLACSpec.cpp TestPlaybackStream.cpp ) foreach(source IN LISTS TEST_SOURCES) - serenity_test("${source}" LibAudio LIBS LibAudio) + serenity_test("${source}" LibAudio LIBS LibAudio LibFileSystem) endforeach() install(DIRECTORY ${FLAC_SPEC_TEST_PATH} DESTINATION usr/Tests/LibAudio/FLAC) + +install(DIRECTORY WAV DESTINATION usr/Tests/LibAudio) diff --git a/Tests/LibAudio/TestWav.cpp b/Tests/LibAudio/TestWav.cpp new file mode 100644 index 0000000000..e8d89f2ec3 --- /dev/null +++ b/Tests/LibAudio/TestWav.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2024, Lee Hanken + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void compare_files(StringView const& in_path, StringView const& out_path) +{ + Array buffer1; + Array buffer2; + + auto original_file = MUST(Core::File::open(in_path, Core::File::OpenMode::Read)); + auto copied_file = MUST(Core::File::open(out_path, Core::File::OpenMode::Read)); + + while (!original_file->is_eof() && !copied_file->is_eof()) { + auto original_bytes = TRY_OR_FAIL(original_file->read_some(buffer1)); + auto copied_bytes = TRY_OR_FAIL(copied_file->read_some(buffer2)); + + EXPECT_EQ(original_bytes, copied_bytes); + } +} + +static void run_test(StringView file_name, int const num_samples, int const channels, u32 const rate) +{ + + constexpr auto format = "RIFF WAVE (.wav)"; + constexpr int bits = 16; + + auto out_file = TRY_OR_FAIL(FileSystem::TempFile::create_temp_file()); + auto out_path = out_file->path(); + +// This makes sure that the tests will run both on target and in Lagom. +#ifdef AK_OS_SERENITY + ByteString in_path = ByteString::formatted("/usr/Tests/LibAudio/WAV/{}", file_name); +#else + ByteString in_path = ByteString::formatted("WAV/{}", file_name); +#endif + + auto loader = TRY_OR_FAIL(Audio::Loader::create(in_path)); + + EXPECT_EQ(loader->format_name(), format); + EXPECT_EQ(loader->sample_rate(), rate); + EXPECT_EQ(loader->num_channels(), channels); + EXPECT_EQ(loader->bits_per_sample(), bits); + EXPECT_EQ(loader->total_samples(), num_samples); + + auto writer = TRY_OR_FAIL(Audio::WavWriter::create_from_file(out_path, rate, channels)); + + int samples_read = 0; + int size = 0; + + do { + auto samples = TRY_OR_FAIL(loader->get_more_samples()); + TRY_OR_FAIL(writer->write_samples(samples.span())); + + size = samples.size(); + samples_read += size; + + } while (size); + + TRY_OR_FAIL(writer->finalize()); + + EXPECT_EQ(samples_read, num_samples); + + compare_files(in_path, out_path); +} + +// 5 seconds, 16-bit audio samples + +TEST_CASE(mono_8khz) +{ + run_test("tone_8000_mono.wav"sv, 40000, 1, 8000); +} + +TEST_CASE(stereo_8khz) +{ + run_test("tone_8000_stereo.wav"sv, 40000, 2, 8000); +} + +TEST_CASE(mono_11khz) +{ + run_test("tone_11025_mono.wav"sv, 55125, 1, 11025); +} + +TEST_CASE(stereo_11khz) +{ + run_test("tone_11025_stereo.wav"sv, 55125, 2, 11025); +} + +TEST_CASE(mono_16khz) +{ + run_test("tone_16000_mono.wav"sv, 80000, 1, 16000); +} + +TEST_CASE(stereo_16khz) +{ + run_test("tone_16000_stereo.wav"sv, 80000, 2, 16000); +} + +TEST_CASE(mono_22khz) +{ + run_test("tone_22050_mono.wav"sv, 110250, 1, 22050); +} + +TEST_CASE(stereo_22khz) +{ + run_test("tone_22050_stereo.wav"sv, 110250, 2, 22050); +} + +TEST_CASE(mono_44khz) +{ + run_test("tone_44100_mono.wav"sv, 220500, 1, 44100); +} + +TEST_CASE(stereo_44khz) +{ + run_test("tone_44100_stereo.wav"sv, 220500, 2, 44100); +} diff --git a/Tests/LibAudio/WAV/tone_11025_mono.wav b/Tests/LibAudio/WAV/tone_11025_mono.wav new file mode 100644 index 0000000000..d7da10bbe7 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_11025_mono.wav differ diff --git a/Tests/LibAudio/WAV/tone_11025_stereo.wav b/Tests/LibAudio/WAV/tone_11025_stereo.wav new file mode 100644 index 0000000000..c5f7139ae0 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_11025_stereo.wav differ diff --git a/Tests/LibAudio/WAV/tone_16000_mono.wav b/Tests/LibAudio/WAV/tone_16000_mono.wav new file mode 100644 index 0000000000..2d3b3c0ffb Binary files /dev/null and b/Tests/LibAudio/WAV/tone_16000_mono.wav differ diff --git a/Tests/LibAudio/WAV/tone_16000_stereo.wav b/Tests/LibAudio/WAV/tone_16000_stereo.wav new file mode 100644 index 0000000000..c0c40b367c Binary files /dev/null and b/Tests/LibAudio/WAV/tone_16000_stereo.wav differ diff --git a/Tests/LibAudio/WAV/tone_22050_mono.wav b/Tests/LibAudio/WAV/tone_22050_mono.wav new file mode 100644 index 0000000000..ca65483ca4 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_22050_mono.wav differ diff --git a/Tests/LibAudio/WAV/tone_22050_stereo.wav b/Tests/LibAudio/WAV/tone_22050_stereo.wav new file mode 100644 index 0000000000..5d0d064c69 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_22050_stereo.wav differ diff --git a/Tests/LibAudio/WAV/tone_44100_mono.wav b/Tests/LibAudio/WAV/tone_44100_mono.wav new file mode 100644 index 0000000000..9d46cdaa7e Binary files /dev/null and b/Tests/LibAudio/WAV/tone_44100_mono.wav differ diff --git a/Tests/LibAudio/WAV/tone_44100_stereo.wav b/Tests/LibAudio/WAV/tone_44100_stereo.wav new file mode 100644 index 0000000000..79569b6f97 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_44100_stereo.wav differ diff --git a/Tests/LibAudio/WAV/tone_8000_mono.wav b/Tests/LibAudio/WAV/tone_8000_mono.wav new file mode 100644 index 0000000000..ecc77bee0e Binary files /dev/null and b/Tests/LibAudio/WAV/tone_8000_mono.wav differ diff --git a/Tests/LibAudio/WAV/tone_8000_stereo.wav b/Tests/LibAudio/WAV/tone_8000_stereo.wav new file mode 100644 index 0000000000..8019218624 Binary files /dev/null and b/Tests/LibAudio/WAV/tone_8000_stereo.wav differ