| 1 |
#include "catch.hpp" |
| 2 |
#include "WavData.hh" |
| 3 |
|
| 4 |
#include "MemoryBufferFile.hh" |
| 5 |
#include "MSXException.hh" |
| 6 |
|
| 7 |
#include "xrange.hh" |
| 8 |
|
| 9 |
using namespace openmsx; |
| 10 |
|
| 11 |
TEST_CASE("WavData, default constructor") |
| 12 |
{ |
| 13 |
WavData wav; |
| 14 |
CHECK(wav.getSize() == 0); |
| 15 |
CHECK(wav.getFreq() == 0); |
| 16 |
for (auto i : xrange(10)) { |
| 17 |
CHECK(wav.getSample(i) == 0); |
| 18 |
} |
| 19 |
} |
| 20 |
|
| 21 |
TEST_CASE("WavData, parser") |
| 22 |
{ |
| 23 |
SECTION("empty file") { |
| 24 |
File file = memory_buffer_file(std::span<const uint8_t>()); |
| 25 |
try { |
| 26 |
WavData wav(std::move(file)); |
| 27 |
CHECK(false); |
| 28 |
} catch (MSXException& e) { |
| 29 |
CHECK(e.getMessage() == "Read beyond end of wav file."); |
| 30 |
} |
| 31 |
} |
| 32 |
SECTION("garbage data") { |
| 33 |
|
| 34 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 35 |
0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, |
| 36 |
0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, |
| 37 |
0x20,0x21,0x22,0x23, |
| 38 |
}); |
| 39 |
try { |
| 40 |
WavData wav(memory_buffer_file(buffer)); |
| 41 |
CHECK(false); |
| 42 |
} catch (MSXException& e) { |
| 43 |
CHECK(e.getMessage() == "Invalid WAV file."); |
| 44 |
} |
| 45 |
} |
| 46 |
SECTION("unsupported format") { |
| 47 |
|
| 48 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 49 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 50 |
0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, |
| 51 |
0x20,0x21,0x22,0x23, |
| 52 |
}); |
| 53 |
try { |
| 54 |
WavData wav(memory_buffer_file(buffer)); |
| 55 |
CHECK(false); |
| 56 |
} catch (MSXException& e) { |
| 57 |
CHECK(e.getMessage() == "WAV format unsupported, must be 8 or 16 bit PCM."); |
| 58 |
} |
| 59 |
} |
| 60 |
SECTION("missing data chunk") { |
| 61 |
|
| 62 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 63 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 64 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x01,0x00, 0x44,0xac,0x00,0x00, 0x88,0x58,0x01,0x00, |
| 65 |
0x02,0x00,0x10,0x00, |
| 66 |
}); |
| 67 |
try { |
| 68 |
WavData wav(memory_buffer_file(buffer)); |
| 69 |
CHECK(false); |
| 70 |
} catch (MSXException& e) { |
| 71 |
CHECK(e.getMessage() == "Read beyond end of wav file."); |
| 72 |
} |
| 73 |
} |
| 74 |
SECTION("data chunk with incorrect length") { |
| 75 |
|
| 76 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 77 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 78 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x01,0x00, 0x44,0xac,0x00,0x00, 0x88,0x58,0x01,0x00, |
| 79 |
0x02,0x00,0x10,0x00, 'd', 'a', 't', 'a', 0x64,0x00,0x00,0x00, |
| 80 |
}); |
| 81 |
try { |
| 82 |
WavData wav(memory_buffer_file(buffer)); |
| 83 |
CHECK(false); |
| 84 |
} catch (MSXException& e) { |
| 85 |
CHECK(e.getMessage() == "Read beyond end of wav file."); |
| 86 |
} |
| 87 |
} |
| 88 |
SECTION("finally a correct, but empty wav file") { |
| 89 |
|
| 90 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 91 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 92 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x01,0x00, 0x44,0xac,0x00,0x00, 0x88,0x58,0x01,0x00, |
| 93 |
0x02,0x00,0x10,0x00, |
| 94 |
'd', 'a', 't', 'a', 0x00,0x00,0x00,0x00, |
| 95 |
}); |
| 96 |
WavData wav(memory_buffer_file(buffer)); |
| 97 |
CHECK(wav.getSize() == 0); |
| 98 |
CHECK(wav.getFreq() == 44100); |
| 99 |
} |
| 100 |
} |
| 101 |
|
| 102 |
TEST_CASE("WavData, content") |
| 103 |
{ |
| 104 |
SECTION("mono, 8 bit") { |
| 105 |
|
| 106 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 107 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 108 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x01,0x00, 0x44,0xac,0x00,0x00, 0x44,0xac,0x00,0x00, |
| 109 |
0x02,0x00,0x08,0x00, |
| 110 |
'd', 'a', 't', 'a', 0x05,0x00,0x00,0x00, |
| 111 |
0x00, 0x45, 0x80, 0xbe, 0xff |
| 112 |
}); |
| 113 |
WavData wav(memory_buffer_file(buffer)); |
| 114 |
CHECK(wav.getSize() == 5); |
| 115 |
CHECK(wav.getFreq() == 44100); |
| 116 |
CHECK(wav.getSample(0) == -0x8000); |
| 117 |
CHECK(wav.getSample(1) == -0x3b00); |
| 118 |
CHECK(wav.getSample(2) == 0x0000); |
| 119 |
CHECK(wav.getSample(3) == 0x3e00); |
| 120 |
CHECK(wav.getSample(4) == 0x7f00); |
| 121 |
CHECK(wav.getSample(5) == 0); |
| 122 |
} |
| 123 |
SECTION("mono, 16 bit") { |
| 124 |
|
| 125 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 126 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 127 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x01,0x00, 0x44,0xac,0x00,0x00, 0x44,0xac,0x00,0x00, |
| 128 |
0x02,0x00,0x10,0x00, |
| 129 |
'd', 'a', 't', 'a', 0x08,0x00,0x00,0x00, |
| 130 |
0x23,0x45, 0x00,0x7e, 0xff,0xff, 0x23,0xc0 |
| 131 |
}); |
| 132 |
WavData wav(memory_buffer_file(buffer)); |
| 133 |
CHECK(wav.getSize() == 4); |
| 134 |
CHECK(wav.getFreq() == 44100); |
| 135 |
CHECK(wav.getSample(0) == 0x4523); |
| 136 |
CHECK(wav.getSample(1) == 0x7e00); |
| 137 |
CHECK(wav.getSample(2) == -0x0001); |
| 138 |
CHECK(wav.getSample(3) == -0x3fdd); |
| 139 |
CHECK(wav.getSample(4) == 0); |
| 140 |
CHECK(wav.getSample(5) == 0); |
| 141 |
} |
| 142 |
SECTION("stereo, 8 bit") { |
| 143 |
|
| 144 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 145 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 146 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x02,0x00, 0x44,0xac,0x00,0x00, 0x44,0xac,0x00,0x00, |
| 147 |
0x02,0x00,0x08,0x00, |
| 148 |
'd', 'a', 't', 'a', 0x08,0x00,0x00,0x00, |
| 149 |
0x00,0xff, 0x40,0xef, 0x80,0xdf, 0xc0,0xcf |
| 150 |
}); |
| 151 |
WavData wav(memory_buffer_file(buffer)); |
| 152 |
CHECK(wav.getSize() == 4); |
| 153 |
CHECK(wav.getFreq() == 44100); |
| 154 |
CHECK(wav.getSample(0) == -0x8000); |
| 155 |
CHECK(wav.getSample(1) == -0x4000); |
| 156 |
CHECK(wav.getSample(2) == 0x0000); |
| 157 |
CHECK(wav.getSample(3) == 0x4000); |
| 158 |
CHECK(wav.getSample(4) == 0); |
| 159 |
} |
| 160 |
SECTION("stereo, 16 bit") { |
| 161 |
|
| 162 |
static constexpr auto buffer = std::to_array<uint8_t>({ |
| 163 |
'R', 'I', 'F', 'F', 0x04,0x05,0x06,0x07, 'W', 'A', 'V', 'E', 'f', 'm', 't' ,' ', |
| 164 |
0x10,0x00,0x00,0x00, 0x01,0x00,0x02,0x00, 0x44,0xac,0x00,0x00, 0x44,0xac,0x00,0x00, |
| 165 |
0x02,0x00,0x10,0x00, |
| 166 |
'd', 'a', 't', 'a', 0x10,0x00,0x00,0x00, |
| 167 |
0x12,0x34,0xff,0xee, 0x56,0x78,0xdd,0xcc, 0x9a,0xbc,0xbb,0xaa, 0xde,0xf0,0x99,0x88, |
| 168 |
}); |
| 169 |
WavData wav(memory_buffer_file(buffer)); |
| 170 |
CHECK(wav.getSize() == 4); |
| 171 |
CHECK(wav.getFreq() == 44100); |
| 172 |
CHECK(wav.getSample(0) == 0x3412); |
| 173 |
CHECK(wav.getSample(1) == 0x7856); |
| 174 |
CHECK(wav.getSample(2) == -0x4366); |
| 175 |
CHECK(wav.getSample(3) == -0x0f22); |
| 176 |
CHECK(wav.getSample(4) == 0); |
| 177 |
} |
| 178 |
} |