1 /***************************************************************************
2 copyright : (C) 2002 - 2008 by Scott Wheeler
3 email : wheeler@kde.org
4 ***************************************************************************/
6 /***************************************************************************
7 * This library is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU Lesser General Public License version *
9 * 2.1 as published by the Free Software Foundation. *
11 * This library is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * Lesser General Public License for more details. *
16 * You should have received a copy of the GNU Lesser General Public *
17 * License along with this library; if not, write to the Free Software *
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
21 * Alternatively, this file is available under the Mozilla Public *
22 * License Version 1.1. You may obtain a copy of the License at *
23 * http://www.mozilla.org/MPL/ *
24 ***************************************************************************/
28 #include <tbytevector.h>
32 #include "mpegheader.h"
34 using namespace TagLib;
36 class MPEG::Header::HeaderPrivate : public RefCounter
43 protectionEnabled(false),
55 bool protectionEnabled;
59 ChannelMode channelMode;
66 ////////////////////////////////////////////////////////////////////////////////
68 ////////////////////////////////////////////////////////////////////////////////
70 MPEG::Header::Header(const ByteVector &data)
72 d = new HeaderPrivate;
76 MPEG::Header::Header(const Header &h) : d(h.d)
81 MPEG::Header::~Header()
87 bool MPEG::Header::isValid() const
92 MPEG::Header::Version MPEG::Header::version() const
97 int MPEG::Header::layer() const
102 bool MPEG::Header::protectionEnabled() const
104 return d->protectionEnabled;
107 int MPEG::Header::bitrate() const
112 int MPEG::Header::sampleRate() const
114 return d->sampleRate;
117 bool MPEG::Header::isPadded() const
122 MPEG::Header::ChannelMode MPEG::Header::channelMode() const
124 return d->channelMode;
127 bool MPEG::Header::isCopyrighted() const
129 return d->isCopyrighted;
132 bool MPEG::Header::isOriginal() const
134 return d->isOriginal;
137 int MPEG::Header::frameLength() const
139 return d->frameLength;
142 int MPEG::Header::samplesPerFrame() const
144 return d->samplesPerFrame;
147 MPEG::Header &MPEG::Header::operator=(const Header &h)
160 ////////////////////////////////////////////////////////////////////////////////
162 ////////////////////////////////////////////////////////////////////////////////
164 void MPEG::Header::parse(const ByteVector &data)
166 if(data.size() < 4 || uchar(data[0]) != 0xff) {
167 debug("MPEG::Header::parse() -- First byte did not match MPEG synch.");
171 std::bitset<32> flags(data.toUInt());
173 // Check for the second byte's part of the MPEG synch
175 if(!flags[23] || !flags[22] || !flags[21]) {
176 debug("MPEG::Header::parse() -- Second byte did not match MPEG synch.");
180 // Set the MPEG version
182 if(!flags[20] && !flags[19])
183 d->version = Version2_5;
184 else if(flags[20] && !flags[19])
185 d->version = Version2;
186 else if(flags[20] && flags[19])
187 d->version = Version1;
189 // Set the MPEG layer
191 if(!flags[18] && flags[17])
193 else if(flags[18] && !flags[17])
195 else if(flags[18] && flags[17])
198 d->protectionEnabled = !flags[16];
202 static const int bitrates[2][3][16] = {
204 { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // layer 1
205 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, // layer 2
206 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 } // layer 3
208 { // Version 2 or 2.5
209 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }, // layer 1
210 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // layer 2
211 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 } // layer 3
215 const int versionIndex = d->version == Version1 ? 0 : 1;
216 const int layerIndex = d->layer > 0 ? d->layer - 1 : 0;
218 // The bitrate index is encoded as the first 4 bits of the 3rd byte,
221 int i = uchar(data[2]) >> 4;
223 d->bitrate = bitrates[versionIndex][layerIndex][i];
225 // Set the sample rate
227 static const int sampleRates[3][4] = {
228 { 44100, 48000, 32000, 0 }, // Version 1
229 { 22050, 24000, 16000, 0 }, // Version 2
230 { 11025, 12000, 8000, 0 } // Version 2.5
233 // The sample rate index is encoded as two bits in the 3nd byte, i.e. xxxx11xx
235 i = uchar(data[2]) >> 2 & 0x03;
237 d->sampleRate = sampleRates[d->version][i];
239 if(d->sampleRate == 0) {
240 debug("MPEG::Header::parse() -- Invalid sample rate.");
244 // The channel mode is encoded as a 2 bit value at the end of the 3nd byte,
247 d->channelMode = ChannelMode((uchar(data[3]) & 0xC0) >> 6);
249 // TODO: Add mode extension for completeness
251 d->isOriginal = flags[2];
252 d->isCopyrighted = flags[3];
253 d->isPadded = flags[9];
255 // Calculate the frame length
258 d->frameLength = 24000 * 2 * d->bitrate / d->sampleRate + int(d->isPadded);
260 d->frameLength = 72000 * d->bitrate / d->sampleRate + int(d->isPadded);
264 static const int samplesPerFrame[3][2] = {
266 { 384, 384 }, // Layer I
267 { 1152, 1152 }, // Layer II
268 { 1152, 576 } // Layer III
271 d->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex];
273 // Now that we're done parsing, set this to be a valid frame.