70 auto raw = file.
mmap();
72 std::array<char, 4> riffID;
74 std::array<char, 4> riffType;
75 std::array<char, 4> fmtID;
84 const auto* header = read<WavHeader>(raw, 0);
85 if ((std::string_view{header->riffID.data(), 4} !=
"RIFF") ||
86 (std::string_view{header->riffType.data(), 4} !=
"WAVE") ||
87 (std::string_view{header->fmtID.data(), 4} !=
"fmt ")) {
90 unsigned bits = header->wBitsPerSample;
91 if ((header->wFormatTag != 1) || (bits !=
one_of(8u, 16u))) {
92 throw MSXException(
"WAV format unsupported, must be 8 or 16 bit PCM.");
94 freq = header->dwSamplesPerSec;
95 unsigned channels = header->wChannels;
98 size_t pos = 20 + header->fmtSize;
102 std::array<char, 4> dataID;
105 const DataHeader* dataHeader;
108 dataHeader = read<DataHeader>(raw, pos);
109 pos +=
sizeof(DataHeader);
110 if (std::string_view{dataHeader->dataID.data(), 4} ==
"data")
break;
112 pos += dataHeader->chunkSize;
116 length = dataHeader->chunkSize / ((bits / 8) * channels);
118 filter.setFreq(freq);
119 auto convertLoop = [&](
const auto* in,
auto convertFunc) {
120 for (
auto i :
xrange(length)) {
121 buffer[i] = filter(convertFunc(*in));
126 convertLoop(read<uint8_t>(raw, pos,
size_t(length) * channels),
127 [](uint8_t u8) {
return int16_t((int16_t(u8) - 0x80) << 8); });
129 convertLoop(read<Endian::L16>(raw, pos,
size_t(length) * channels),