Tag Parser  9.1.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/io/binaryreader.h>
6 
7 using namespace std;
8 using namespace CppUtilities;
9 
10 namespace TagParser {
11 
15 const char *mpegChannelModeString(MpegChannelMode channelMode)
16 {
17  switch (channelMode) {
18  case MpegChannelMode::Stereo:
19  return "2 channels: stereo";
20  case MpegChannelMode::JointStereo:
21  return "2 channels: joint stereo";
22  case MpegChannelMode::DualChannel:
23  return "2 channels: dual channel";
24  case MpegChannelMode::SingleChannel:
25  return "1 channel: single channel";
26  default:
27  return nullptr;
28  }
29 }
30 
36 const std::uint16_t MpegAudioFrame::s_bitrateTable[0x2][0x3][0xF] = { { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
37  { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
38  { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
39  { { 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 },
40  { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
41 
47 void MpegAudioFrame::parseHeader(BinaryReader &reader, Diagnostics &diag)
48 {
49  m_header = reader.readUInt32BE();
50  if (!isValid()) {
51  diag.emplace_back(DiagLevel::Critical, "Header is invalid.", "parsing MPEG audio frame header");
52  throw InvalidDataException();
53  }
54  reader.stream()->seekg(s_xingHeaderOffset - 4, ios_base::cur);
55  m_xingHeader = reader.readUInt64BE();
56  m_xingHeaderFlags = static_cast<XingHeaderFlags>(m_xingHeader & 0xffffffffuL);
57  if (isXingHeaderAvailable()) {
58  if (isXingFramefieldPresent()) {
59  m_xingFramefield = reader.readUInt32BE();
60  }
61  if (isXingBytesfieldPresent()) {
62  m_xingBytesfield = reader.readUInt32BE();
63  }
64  if (isXingTocFieldPresent()) {
65  reader.stream()->seekg(64, ios_base::cur);
66  }
67  if (isXingQualityIndicatorFieldPresent()) {
68  m_xingQualityIndicator = reader.readUInt32BE();
69  }
70  }
71 }
72 
76 double MpegAudioFrame::mpegVersion() const
77 {
78  switch (m_header & 0x180000u) {
79  case 0x180000u:
80  return 1.0;
81  case 0x100000u:
82  return 2.0;
83  case 0x0u:
84  return 2.5;
85  default:
86  return 0.0;
87  }
88 }
89 
93 int MpegAudioFrame::layer() const
94 {
95  switch (m_header & 0x60000u) {
96  case 0x60000u:
97  return 1;
98  case 0x40000u:
99  return 2;
100  case 0x20000u:
101  return 3;
102  default:
103  return 0;
104  }
105 }
106 
110 std::uint32_t MpegAudioFrame::samplingFrequency() const
111 {
112  switch (m_header & 0xc00u) {
113  case 0xc00u:
114  return 0;
115  case 0x800u:
116  switch (m_header & 0x180000u) {
117  case 0x180000u:
118  return 32000;
119  case 0x100000u:
120  return 16000;
121  case 0x0u:
122  return 8000u;
123  }
124  break;
125  case 0x400u:
126  switch (m_header & 0x180000u) {
127  case 0x180000u:
128  return 48000;
129  case 0x100000u:
130  return 24000;
131  case 0x0u:
132  return 12000;
133  }
134  break;
135  case 0x0u:
136  switch (m_header & 0x180000u) {
137  case 0x180000u:
138  return 44100;
139  case 0x100000:
140  return 22050;
141  case 0x0u:
142  return 11025;
143  }
144  break;
145  }
146  return 0;
147 }
148 
152 MpegChannelMode MpegAudioFrame::channelMode() const
153 {
154  if (isValid()) {
155  switch (m_header & 0xc0u) {
156  case 0xc0u:
157  return MpegChannelMode::SingleChannel;
158  case 0x80u:
159  return MpegChannelMode::DualChannel;
160  case 0x40u:
161  return MpegChannelMode::JointStereo;
162  case 0x00:
163  return MpegChannelMode::Stereo;
164  default:;
165  }
166  }
167  return MpegChannelMode::Unspecifed;
168 }
169 
173 std::uint32_t MpegAudioFrame::sampleCount() const
174 {
175  switch (m_header & 0x60000u) {
176  case 0x60000u:
177  return 384u;
178  case 0x40000u:
179  return 1152u;
180  case 0x20000u:
181  switch (m_header & 0x180000u) {
182  case 0x180000u:
183  return 1152u;
184  case 0x100000u:
185  case 0x0u:
186  return 576u;
187  }
188  default:;
189  }
190  return 0;
191 }
192 
196 std::uint32_t MpegAudioFrame::size() const
197 {
198  switch (m_header & 0x60000u) {
199  case 0x60000u:
200  return static_cast<std::uint32_t>(
201  ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
202  + static_cast<double>(paddingSize()));
203  case 0x40000u:
204  case 0x20000u:
205  return static_cast<std::uint32_t>(
206  ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
207  + static_cast<double>(paddingSize()));
208  default:
209  return 0;
210  }
211 }
212 
213 } // namespace TagParser
TagParser::MpegChannelMode
MpegChannelMode
Specifies the channel mode.
Definition: mpegaudioframe.h:18
mpegaudioframe.h
TagParser::Diagnostics
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TagParser::mpegChannelModeString
const TAG_PARSER_EXPORT char * mpegChannelModeString(MpegChannelMode channelMode)
Returns the string representation for the specified channelMode.
Definition: mpegaudioframe.cpp:15
CppUtilities
Definition: abstractcontainer.h:15
TagParser::InvalidDataException
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:25
TagParser::MatroskaTagIds::TrackSpecific::bitrate
constexpr const TAG_PARSER_EXPORT char * bitrate()
The track's bit rate in bits per second.
Definition: matroskatagid.h:463