#include #include #include #include #include #include #include using namespace XCEngine::Resources; using namespace XCEngine::Containers; namespace { #pragma pack(push, 1) struct WAVFileHeader { char riff[4]; uint32_t fileSize; char wave[4]; char fmt[4]; uint32_t fmtSize; uint16_t audioFormat; uint16_t numChannels; uint32_t sampleRate; uint32_t byteRate; uint16_t blockAlign; uint16_t bitsPerSample; char data[4]; uint32_t dataSize; }; #pragma pack(pop) void CreateTestWAVFile(const char* filepath, uint16_t channels, uint32_t sampleRate, uint16_t bitsPerSample, uint32_t numSamples) { WAVFileHeader header = {}; header.riff[0] = 'R'; header.riff[1] = 'I'; header.riff[2] = 'F'; header.riff[3] = 'F'; header.wave[0] = 'W'; header.wave[1] = 'A'; header.wave[2] = 'V'; header.wave[3] = 'E'; header.fmt[0] = 'f'; header.fmt[1] = 'm'; header.fmt[2] = 't'; header.fmt[3] = ' '; header.fmtSize = 16; header.audioFormat = 1; header.numChannels = channels; header.sampleRate = sampleRate; header.bitsPerSample = bitsPerSample; header.blockAlign = channels * bitsPerSample / 8; header.byteRate = sampleRate * header.blockAlign; header.data[0] = 'd'; header.data[1] = 'a'; header.data[2] = 't'; header.data[3] = 'a'; header.dataSize = numSamples * header.blockAlign; header.fileSize = 36 + header.dataSize; std::vector wavData(sizeof(WAVFileHeader) + header.dataSize, 0); std::memcpy(wavData.data(), &header, sizeof(WAVFileHeader)); std::ofstream file(filepath, std::ios::binary); file.write(reinterpret_cast(wavData.data()), wavData.size()); } TEST(AudioLoader, ParseWAV_Mono44100_16bit) { const char* testPath = "test_mono_44100.wav"; CreateTestWAVFile(testPath, 1, 44100, 16, 44100); AudioLoader loader; LoadResult result = loader.Load(testPath); EXPECT_TRUE(result); if (result) { AudioClip* clip = static_cast(result.resource); EXPECT_EQ(clip->GetSampleRate(), 44100u); EXPECT_EQ(clip->GetChannels(), 1u); EXPECT_EQ(clip->GetBitsPerSample(), 16u); EXPECT_GT(clip->GetDuration(), 0.0f); } std::remove(testPath); } TEST(AudioLoader, ParseWAV_Stereo48000_16bit) { const char* testPath = "test_stereo_48000.wav"; CreateTestWAVFile(testPath, 2, 48000, 16, 4800); AudioLoader loader; LoadResult result = loader.Load(testPath); EXPECT_TRUE(result); if (result) { AudioClip* clip = static_cast(result.resource); EXPECT_EQ(clip->GetSampleRate(), 48000u); EXPECT_EQ(clip->GetChannels(), 2u); EXPECT_EQ(clip->GetBitsPerSample(), 16u); } std::remove(testPath); } TEST(AudioLoader, GetResourceType) { AudioLoader loader; EXPECT_EQ(loader.GetResourceType(), ResourceType::AudioClip); } TEST(AudioLoader, GetSupportedExtensions) { AudioLoader loader; auto extensions = loader.GetSupportedExtensions(); EXPECT_GE(extensions.Size(), 1u); } TEST(AudioLoader, CanLoad) { AudioLoader loader; EXPECT_TRUE(loader.CanLoad("test.wav")); EXPECT_TRUE(loader.CanLoad("test.mp3")); EXPECT_TRUE(loader.CanLoad("test.ogg")); EXPECT_FALSE(loader.CanLoad("test.txt")); EXPECT_FALSE(loader.CanLoad("test.png")); } TEST(AudioLoader, LoadInvalidPath) { AudioLoader loader; LoadResult result = loader.Load("invalid/path/audio.wav"); EXPECT_FALSE(result); } } // namespace