Tag Parser 12.1.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
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"
56 % numberToString<std::int64_t>(reader.stream()->tellg() - static_cast<std::streamoff>(4), 16)
57 + " is invalid.",
58 "parsing MPEG audio frame header");
60 }
61
62 // read XING header (see https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header#XINGHeader)
63 if (size() < s_xingHeaderOffset - 4 + 8) {
64 return;
65 }
66 reader.stream()->seekg(s_xingHeaderOffset - 4, ios_base::cur);
67 m_xingHeader = reader.readUInt64BE();
69 m_xingHeaderFlags = static_cast<XingHeaderFlags>(m_xingHeader & 0xffffffffuL);
71 m_xingFramefield = reader.readUInt32BE();
72 }
74 m_xingBytesfield = reader.readUInt32BE();
75 }
77 reader.stream()->seekg(0x64, ios_base::cur);
78 }
80 m_xingQualityIndicator = reader.readUInt32BE();
81 }
82 }
83}
84
89{
90 switch (m_header & 0x180000u) {
91 case 0x180000u:
92 return 1.0;
93 case 0x100000u:
94 return 2.0;
95 case 0x0u:
96 return 2.5;
97 default:
98 return 0.0;
99 }
100}
101
106{
107 switch (m_header & 0x60000u) {
108 case 0x60000u:
109 return 1;
110 case 0x40000u:
111 return 2;
112 case 0x20000u:
113 return 3;
114 default:
115 return 0;
116 }
117}
118
123{
124 switch (m_header & 0xc00u) {
125 case 0xc00u:
126 return 0;
127 case 0x800u:
128 switch (m_header & 0x180000u) {
129 case 0x180000u:
130 return 32000;
131 case 0x100000u:
132 return 16000;
133 case 0x0u:
134 return 8000u;
135 }
136 break;
137 case 0x400u:
138 switch (m_header & 0x180000u) {
139 case 0x180000u:
140 return 48000;
141 case 0x100000u:
142 return 24000;
143 case 0x0u:
144 return 12000;
145 }
146 break;
147 case 0x0u:
148 switch (m_header & 0x180000u) {
149 case 0x180000u:
150 return 44100;
151 case 0x100000:
152 return 22050;
153 case 0x0u:
154 return 11025;
155 }
156 break;
157 }
158 return 0;
159}
160
165{
166 if (isValid()) {
167 switch (m_header & 0xc0u) {
168 case 0xc0u:
170 case 0x80u:
172 case 0x40u:
174 case 0x00:
176 default:;
177 }
178 }
180}
181
185std::uint32_t MpegAudioFrame::sampleCount() const
186{
187 switch (m_header & 0x60000u) {
188 case 0x60000u:
189 return 384u;
190 case 0x40000u:
191 return 1152u;
192 case 0x20000u:
193 switch (m_header & 0x180000u) {
194 case 0x180000u:
195 return 1152u;
196 case 0x100000u:
197 case 0x0u:
198 return 576u;
199 }
200 default:;
201 }
202 return 0;
203}
204
208std::uint32_t MpegAudioFrame::size() const
209{
210 switch (m_header & 0x60000u) {
211 case 0x60000u: // layer 1
212 return static_cast<std::uint32_t>(
213 ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
214 + static_cast<double>(paddingSize()))
215 * 4;
216 case 0x40000u: // layer 2
217 case 0x20000u: // layer 3
218 return static_cast<std::uint32_t>(
219 ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
220 + static_cast<double>(paddingSize()));
221 default:
222 return 0;
223 }
224}
225
226} // namespace TagParser
The Diagnostics class is a container for DiagMessage.
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.