Tag Parser  7.1.0
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.
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:25
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:9