Tag Parser  7.0.3
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 IoUtilities;
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 
31 const uint64 MpegAudioFrame::m_xingHeaderOffset = 0x24;
32 
38 const int MpegAudioFrame::m_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 
44 const uint32 MpegAudioFrame::m_sync = 0xFFE00000u;
45 
51 void MpegAudioFrame::parseHeader(BinaryReader &reader)
52 {
53  m_header = reader.readUInt32BE();
54  if (!isValid()) {
55  throw InvalidDataException();
56  }
57  reader.stream()->seekg(m_xingHeaderOffset - 4, ios_base::cur);
58  m_xingHeader = reader.readUInt64BE();
59  m_xingHeaderFlags = static_cast<XingHeaderFlags>(m_xingHeader & 0xffffffffuL);
60  if (isXingHeaderAvailable()) {
61  if (isXingFramefieldPresent()) {
62  m_xingFramefield = reader.readUInt32BE();
63  }
64  if (isXingBytesfieldPresent()) {
65  m_xingBytesfield = reader.readUInt32BE();
66  }
67  if (isXingTocFieldPresent()) {
68  reader.stream()->seekg(64, ios_base::cur);
69  }
70  if (isXingQualityIndicatorFieldPresent()) {
71  m_xingQualityIndicator = reader.readUInt32BE();
72  }
73  }
74 }
75 
79 double MpegAudioFrame::mpegVersion() const
80 {
81  switch (m_header & 0x180000u) {
82  case 0x180000u:
83  return 1.0;
84  case 0x100000u:
85  return 2.0;
86  case 0x0u:
87  return 2.5;
88  default:
89  return 0.0;
90  }
91 }
92 
96 int MpegAudioFrame::layer() const
97 {
98  switch (m_header & 0x60000u) {
99  case 0x60000u:
100  return 1;
101  case 0x40000u:
102  return 2;
103  case 0x20000u:
104  return 3;
105  default:
106  return 0;
107  }
108 }
109 
113 uint32 MpegAudioFrame::samplingFrequency() const
114 {
115  switch (m_header & 0xc00u) {
116  case 0xc00u:
117  return 0;
118  case 0x800u:
119  switch (m_header & 0x180000u) {
120  case 0x180000u:
121  return 32000;
122  case 0x100000u:
123  return 16000;
124  case 0x0u:
125  return 8000u;
126  }
127  break;
128  case 0x400u:
129  switch (m_header & 0x180000u) {
130  case 0x180000u:
131  return 48000;
132  case 0x100000u:
133  return 24000;
134  case 0x0u:
135  return 12000;
136  }
137  break;
138  case 0x0u:
139  switch (m_header & 0x180000u) {
140  case 0x180000u:
141  return 44100;
142  case 0x100000:
143  return 22050;
144  case 0x0u:
145  return 11025;
146  }
147  break;
148  }
149  return 0;
150 }
151 
155 MpegChannelMode MpegAudioFrame::channelMode() const
156 {
157  if (isValid()) {
158  switch (m_header & 0xc0u) {
159  case 0xc0u:
160  return MpegChannelMode::SingleChannel;
161  case 0x80u:
162  return MpegChannelMode::DualChannel;
163  case 0x40u:
164  return MpegChannelMode::JointStereo;
165  case 0x00:
166  return MpegChannelMode::Stereo;
167  default:;
168  }
169  }
170  return MpegChannelMode::Unspecifed;
171 }
172 
176 uint32 MpegAudioFrame::sampleCount() const
177 {
178  switch (m_header & 0x60000u) {
179  case 0x60000u:
180  return 384u;
181  case 0x40000u:
182  return 1152u;
183  case 0x20000u:
184  switch (m_header & 0x180000u) {
185  case 0x180000u:
186  return 1152u;
187  case 0x100000u:
188  case 0x0u:
189  return 576u;
190  }
191  default:;
192  }
193  return 0;
194 }
195 
199 uint32 MpegAudioFrame::size() const
200 {
201  switch (m_header & 0x60000u) {
202  case 0x60000u:
203  return static_cast<uint32>(
204  ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
205  + static_cast<double>(paddingSize()));
206  case 0x40000u:
207  case 0x20000u:
208  return static_cast<uint32>(
209  ((static_cast<double>(bitrate()) * 1024.0 / 8.0) / static_cast<double>(samplingFrequency())) * static_cast<double>(sampleCount())
210  + static_cast<double>(paddingSize()));
211  default:
212  return 0;
213  }
214 }
215 
216 } // namespace TagParser
MpegChannelMode
Specifies the channel mode.
TAG_PARSER_EXPORT const char * bitrate()
The track&#39;s bit rate in bits per second.
STL namespace.
Contains utility classes helping to read and write streams.
TAG_PARSER_EXPORT const char * mpegChannelModeString(MpegChannelMode channelMode)
Returns the string representation for the specified channelMode.