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> 12 using namespace ChronoUtilities;
25 void WaveFormatHeader::parse(IoUtilities::BinaryReader &reader)
28 parseExt(reader, 16, diag);
39 pair<MediaFormat, uint64> WaveFormatHeader::parseExt(IoUtilities::BinaryReader &reader, uint64 maxSize,
Diagnostics &diag)
41 auto result = make_pair<MediaFormat, uint64>(GeneralMediaFormat::Unknown, 0);
43 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated.",
"parsing WAVE format header");
47 formatTag = reader.readUInt16LE();
48 result.first = format();
50 sampleRate = reader.readUInt32LE();
51 bytesPerSecond = reader.readUInt32LE();
52 chunkSize = reader.readUInt16LE();
53 bitsPerSample = reader.readUInt16LE();
57 if (result.first.general == GeneralMediaFormat::Pcm) {
60 if ((maxSize -= 16) < 2) {
61 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated (extended header missing).",
"parsing WAVE format header");
64 const auto extensionSize = reader.readUInt16LE();
66 if ((maxSize -= 2) < 2) {
67 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" segment is truncated (extended header truncated).",
"parsing WAVE format header");
72 if (formatTag != 65534) {
73 reader.stream()->seekg(extensionSize, ios_base::cur);
74 result.second += extensionSize;
79 if (extensionSize != 22) {
80 diag.emplace_back(DiagLevel::Warning,
"\"fmt \" extended header has unexptected size.",
"parsing WAVE format header");
83 bitsPerSample = reader.readUInt16LE();
84 reader.stream()->seekg(4, ios_base::cur);
85 const auto guid1 = reader.readUInt64BE();
86 const auto guid2 = reader.readUInt64BE();
89 case 0x000800000aa00389b71:
91 case 0x0100000000001000ul:
94 case 0x0300000000001000ul:
118 return GeneralMediaFormat::Unknown;
131 WaveAudioStream::WaveAudioStream(iostream &stream, uint64 startOffset)
166 const string context(
"parsing RIFF/WAVE header");
170 if (
m_reader.readUInt32BE() != 0x52494646u) {
174 if (
m_reader.readUInt32BE() != 0x57415645u) {
177 while (!m_dataOffset) {
178 const auto segmentId =
m_reader.readUInt32BE();
179 auto restHeaderLen =
m_reader.readUInt32LE();
186 restHeaderLen -= bytesRead;
189 m_dataOffset = static_cast<uint64>(
m_istream->tellg());
196 m_istream->seekg(restHeaderLen, ios_base::cur);
201 m_istream->seekg(static_cast<streamoff>(m_dataOffset));
206 ? ((static_cast<double>(
m_size) * 8.0)
TAG_PARSER_EXPORT byte channelCount(byte config)
Returns the channel count for the specified MPEG-4 channel config.
uint32 sampleCount() const
Returns the sample count if known; otherwise returns 0.
IoUtilities::BinaryReader m_reader
~WaveAudioStream() override
Destroys the track.
The MpegAudioFrame class is used to parse MPEG audio frames.
static void addInfo(const WaveFormatHeader &waveHeader, AbstractTrack &track)
Adds the information from the specified waveHeader to the specified track.
constexpr bool isXingFramefieldPresent() const
Returns an indication whether the Xing frame field is present.
ChronoUtilities::TimeSpan m_duration
TrackType type() const override
Returns the type of the track if known; otherwise returns TrackType::Unspecified.
The exception that is thrown when the data to be parsed holds no parsable information (e....
void parseHeader(IoUtilities::BinaryReader &reader, Diagnostics &diag)
Parses the header read using the specified reader.
uint16 bitrate() const
Returns the bitrate of the frame if known; otherwise returns 0.
static void addInfo(const MpegAudioFrame &frame, AbstractTrack &track)
Adds the information from the specified frame to the specified track.
The AbstractTrack class parses and stores technical information about video, audio and other kinds of...
uint32 m_samplingFrequency
Contains all classes and functions of the TagInfo library.
constexpr uint32 xingFrameCount() const
Returns an indication whether the Xing frame count is present.
TrackType
Specifies the track type.
uint32 samplingFrequency() const
Returns the sampeling frequency of the frame if known; otherwise returns 0.
void internalParseHeader(Diagnostics &diag) override
This method is internally called to parse header information.
The Diagnostics class is a container for DiagMessage.