Tag Parser 10.3.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
mpegaudioframe.cpp
Go to the documentation of this file.
1#include "./mpegaudioframe.h"
2
3#include "../exceptions.h"
4
5#include <c++utilities/conversion/stringbuilder.h>
6#include <c++utilities/conversion/stringconversion.h>
7#include <c++utilities/io/binaryreader.h>
8
9using namespace std;
10using namespace CppUtilities;
11
12namespace TagParser {
13
17std::string_view mpegChannelModeString(MpegChannelMode channelMode)
18{
19 switch (channelMode) {
21 return "2 channels: stereo";
23 return "2 channels: joint stereo";
25 return "2 channels: dual channel";
27 return "1 channel: single channel";
28 default:
29 return std::string_view();
30 }
31}
32
38const std::uint16_t MpegAudioFrame::s_bitrateTable[0x2][0x3][0xF] = { { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
39 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
40 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
41 { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 },
42 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
43
49void MpegAudioFrame::parseHeader(BinaryReader &reader, Diagnostics &diag)
50{
51 // read MPEG audio frame header
52 m_header = reader.readUInt32BE();
53 if (!isValid()) {
54 diag.emplace_back(DiagLevel::Critical,
55 "Frame 0x" % numberToString(m_header, 16u) % " at 0x" % numberToString<std::int64_t>(reader.stream()->tellg() - 4l, 16) + " is invalid.",
56 "parsing MPEG audio frame header");
58 }
59
60 // read XING header (see https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header#XINGHeader)
61 if (size() < s_xingHeaderOffset - 4 + 8) {
62 return;
63 }
64 reader.stream()->seekg(s_xingHeaderOffset - 4, ios_base::cur);
65 m_xingHeader = reader.readUInt64BE();
67 m_xingHeaderFlags = static_cast<XingHeaderFlags>(m_xingHeader & 0xffffffffuL);
69 m_xingFramefield = reader.readUInt32BE();
70 }
72 m_xingBytesfield = reader.readUInt32BE();
73 }
75 reader.stream()->seekg(64, ios_base::cur);
76 }
78 m_xingQualityIndicator = reader.readUInt32BE();
79 }
80 }
81}
82
87{
88 switch (m_header & 0x180000u) {
89 case 0x180000u:
90 return 1.0;
91 case 0x100000u:
92 return 2.0;
93 case 0x0u:
94 return 2.5;
95 default:
96 return 0.0;
97 }
98}
99
104{
105 switch (m_header & 0x60000u) {
106 case 0x60000u:
107 return 1;
108 case 0x40000u:
109 return 2;
110 case 0x20000u:
111 return 3;
112 default:
113 return 0;
114 }
115}
116
121{
122 switch (m_header & 0xc00u) {
123 case 0xc00u:
124 return 0;
125 case 0x800u:
126 switch (m_header & 0x180000u) {
127 case 0x180000u:
128 return 32000;
129 case 0x100000u:
130 return 16000;
131 case 0x0u:
132 return 8000u;
133 }
134 break;
135 case 0x400u:
136 switch (m_header & 0x180000u) {
137 case 0x180000u:
138 return 48000;
139 case 0x100000u:
140 return 24000;
141 case 0x0u:
142 return 12000;
143 }
144 break;
145 case 0x0u:
146 switch (m_header & 0x180000u) {
147 case 0x180000u:
148 return 44100;
149 case 0x100000:
150 return 22050;
151 case 0x0u:
152 return 11025;
153 }
154 break;
155 }
156 return 0;
157}
158
163{
164 if (isValid()) {
165 switch (m_header & 0xc0u) {
166 case 0xc0u:
168 case 0x80u:
170 case 0x40u:
172 case 0x00:
174 default:;
175 }
176 }
178}
179
183std::uint32_t MpegAudioFrame::sampleCount() const
184{
185 switch (m_header & 0x60000u) {
186 case 0x60000u:
187 return 384u;
188 case 0x40000u:
189 return 1152u;
190 case 0x20000u:
191 switch (m_header & 0x180000u) {
192 case 0x180000u:
193 return 1152u;
194 case 0x100000u:
195 case 0x0u:
196 return 576u;
197 }
198 default:;
199 }
200 return 0;
201}
202
206std::uint32_t MpegAudioFrame::size() const
207{
208 switch (m_header & 0x60000u) {
209 case 0x60000u: // layer 1
210 return static_cast<std::uint32_t>(
211 ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
212 + static_cast<double>(paddingSize()))
213 * 4;
214 case 0x40000u: // layer 2
215 case 0x20000u: // layer 3
216 return static_cast<std::uint32_t>(
217 ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
218 + static_cast<double>(paddingSize()));
219 default:
220 return 0;
221 }
222}
223
224} // namespace TagParser
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:25
std::uint32_t size() const
Returns the size if known; otherwise returns 0.
constexpr bool isXingQualityIndicatorFieldPresent() const
Returns an indication whether the Xing quality indicator field is present.
std::uint32_t samplingFrequency() const
Returns the sampeling frequency of the frame if known; otherwise returns 0.
MpegChannelMode channelMode() const
Returns the channel mode if known; otherwise returns MpegChannelMode::Unspecifed.
constexpr std::uint32_t paddingSize() const
Returns the padding size if known; otherwise returns 0.
std::uint32_t sampleCount() const
Returns the sample count if known; otherwise returns 0.
constexpr bool isXingTocFieldPresent() const
Returns an indication whether the Xing TOC is present.
constexpr bool isValid() const
Returns an indication whether the frame is valid.
int layer() const
Returns the MPEG layer if known (1, 2, or 3); otherwise returns 0.
std::uint16_t bitrate() const
Returns the bitrate of the frame if known; otherwise returns 0.
constexpr bool isXingBytesfieldPresent() const
Returns an indication whether the Xing bytes field is present.
void parseHeader(CppUtilities::BinaryReader &reader, Diagnostics &diag)
Parses the header read using the specified reader.
constexpr bool isXingHeaderAvailable() const
Returns an indication whether a Xing header is present.
double mpegVersion() const
Returns the MPEG version if known (1.0, 2.0 or 2.5); otherwise returns 0.
constexpr bool isXingFramefieldPresent() const
Returns an indication whether the Xing frame field is present.
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TAG_PARSER_EXPORT std::string_view mpegChannelModeString(MpegChannelMode channelMode)
Returns the string representation for the specified channelMode.
MpegChannelMode
Specifies the channel mode.