3 #include "../mpegaudio/mpegaudioframestream.h"
5 #include "../exceptions.h"
6 #include "../mediaformat.h"
8 #include <c++utilities/conversion/stringconversion.h>
9 #include <c++utilities/io/binaryreader.h>
25 std::uint64_t WaveFormatHeader::parse(CppUtilities::BinaryReader &reader, std::uint64_t maxSize,
Diagnostics &diag)
27 uint64_t bytesRead = 0;
29 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated.",
"parsing WAVE format header");
33 formatTag = reader.readUInt16LE();
35 sampleRate = reader.readUInt32LE();
36 bytesPerSecond = reader.readUInt32LE();
37 chunkSize = reader.readUInt16LE();
38 bitsPerSample = reader.readUInt16LE();
42 if (formatTag == 0x0001u || formatTag == 0x0003u) {
45 if ((maxSize -= 16) < 2) {
46 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated (extended header missing).",
"parsing WAVE format header");
49 const auto extensionSize = reader.readUInt16LE();
51 if ((maxSize -= 2) < 2) {
52 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated (extended header truncated).",
"parsing WAVE format header");
57 if (formatTag != 65534) {
58 reader.stream()->seekg(extensionSize, ios_base::cur);
59 bytesRead += extensionSize;
64 if (extensionSize != 22) {
65 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" extended header has unexptected size.",
"parsing WAVE format header");
68 bitsPerSample = reader.readUInt16LE();
69 channelMask = reader.readUInt32LE();
70 guid1 = reader.readUInt64BE();
71 guid2 = reader.readUInt64BE();
72 return bytesRead += 22;
91 case 0x000800000aa00389b71:
93 case 0x0100000000001000ul:
95 case 0x0300000000001000ul:
100 return GeneralMediaFormat::Unknown;
113 WaveAudioStream::WaveAudioStream(iostream &stream, std::uint64_t startOffset)
149 const string context(
"parsing RIFF/WAVE header");
153 if (
m_reader.readUInt32BE() != 0x52494646u) {
157 if (
m_reader.readUInt32BE() != 0x57415645u) {
160 while (!m_dataOffset) {
161 const auto segmentId =
m_reader.readUInt32BE();
162 auto restHeaderLen =
m_reader.readUInt32LE();
166 const auto bytesRead = waveHeader.
parse(
m_reader, restHeaderLen, diag);
168 restHeaderLen -= bytesRead;
171 m_dataOffset = static_cast<std::uint64_t>(
m_istream->tellg());
178 m_istream->seekg(restHeaderLen, ios_base::cur);
183 m_istream->seekg(static_cast<streamoff>(m_dataOffset));