TestWav.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2024, Lee Hanken <github-12-2017-ds8@leehanken.uk>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/ByteString.h>
  7. #include <AK/LexicalPath.h>
  8. #include <LibAudio/WavLoader.h>
  9. #include <LibAudio/WavWriter.h>
  10. #include <LibCore/Directory.h>
  11. #include <LibCore/File.h>
  12. #include <LibFileSystem/FileSystem.h>
  13. #include <LibFileSystem/TempFile.h>
  14. #include <LibTest/TestCase.h>
  15. static void compare_files(StringView const& in_path, StringView const& out_path)
  16. {
  17. Array<u8, 4096> buffer1;
  18. Array<u8, 4096> buffer2;
  19. auto original_file = MUST(Core::File::open(in_path, Core::File::OpenMode::Read));
  20. auto copied_file = MUST(Core::File::open(out_path, Core::File::OpenMode::Read));
  21. while (!original_file->is_eof() && !copied_file->is_eof()) {
  22. auto original_bytes = TRY_OR_FAIL(original_file->read_some(buffer1));
  23. auto copied_bytes = TRY_OR_FAIL(copied_file->read_some(buffer2));
  24. EXPECT_EQ(original_bytes, copied_bytes);
  25. }
  26. }
  27. static void run_test(StringView file_name, int const num_samples, int const channels, u32 const rate)
  28. {
  29. constexpr auto format = "RIFF WAVE (.wav)";
  30. constexpr int bits = 16;
  31. auto out_file = TRY_OR_FAIL(FileSystem::TempFile::create_temp_file());
  32. auto out_path = out_file->path();
  33. ByteString in_path = ByteString::formatted("WAV/{}", file_name);
  34. auto loader = TRY_OR_FAIL(Audio::Loader::create(in_path));
  35. EXPECT_EQ(loader->format_name(), format);
  36. EXPECT_EQ(loader->sample_rate(), rate);
  37. EXPECT_EQ(loader->num_channels(), channels);
  38. EXPECT_EQ(loader->bits_per_sample(), bits);
  39. EXPECT_EQ(loader->total_samples(), num_samples);
  40. auto writer = TRY_OR_FAIL(Audio::WavWriter::create_from_file(out_path, rate, channels));
  41. int samples_read = 0;
  42. int size = 0;
  43. do {
  44. auto samples = TRY_OR_FAIL(loader->get_more_samples());
  45. TRY_OR_FAIL(writer->write_samples(samples.span()));
  46. size = samples.size();
  47. samples_read += size;
  48. } while (size);
  49. TRY_OR_FAIL(writer->finalize());
  50. EXPECT_EQ(samples_read, num_samples);
  51. compare_files(in_path, out_path);
  52. }
  53. // 5 seconds, 16-bit audio samples
  54. TEST_CASE(mono_8khz)
  55. {
  56. run_test("tone_8000_mono.wav"sv, 40000, 1, 8000);
  57. }
  58. TEST_CASE(stereo_8khz)
  59. {
  60. run_test("tone_8000_stereo.wav"sv, 40000, 2, 8000);
  61. }
  62. TEST_CASE(mono_11khz)
  63. {
  64. run_test("tone_11025_mono.wav"sv, 55125, 1, 11025);
  65. }
  66. TEST_CASE(stereo_11khz)
  67. {
  68. run_test("tone_11025_stereo.wav"sv, 55125, 2, 11025);
  69. }
  70. TEST_CASE(mono_16khz)
  71. {
  72. run_test("tone_16000_mono.wav"sv, 80000, 1, 16000);
  73. }
  74. TEST_CASE(stereo_16khz)
  75. {
  76. run_test("tone_16000_stereo.wav"sv, 80000, 2, 16000);
  77. }
  78. TEST_CASE(mono_22khz)
  79. {
  80. run_test("tone_22050_mono.wav"sv, 110250, 1, 22050);
  81. }
  82. TEST_CASE(stereo_22khz)
  83. {
  84. run_test("tone_22050_stereo.wav"sv, 110250, 2, 22050);
  85. }
  86. TEST_CASE(mono_44khz)
  87. {
  88. run_test("tone_44100_mono.wav"sv, 220500, 1, 44100);
  89. }
  90. TEST_CASE(stereo_44khz)
  91. {
  92. run_test("tone_44100_stereo.wav"sv, 220500, 2, 44100);
  93. }