First public contribution.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
20 // Masks used for reading bits.
22 static const TInt KMP3Sync1Mask = 0xff; // 11111111
23 static const TInt KMP3Sync2Mask = 0xe0; // 11100000
24 static const TInt KMP3VersionMask = 0x18; // 00011000
25 static const TInt KMP3LayerMask = 0x06; // 00000110
26 static const TInt KMP3BitrateMask = 0xf0; // 11110000
27 static const TInt KMP3SampleRateMask = 0x0c; // 00001100
28 static const TInt KMP3PaddingMask = 0x02; // 00000010
30 static const TInt KBitsPerByte = 8;
33 // Macros for retrieving the values.
35 #define MP3_GET_SYNC1(d) (d & KMP3Sync1Mask)
36 #define MP3_GET_SYNC2(d) ((d & KMP3Sync2Mask) >> 5)
37 #define MP3_GET_VERSION(d) ((d & KMP3VersionMask) >> 3)
38 #define MP3_GET_LAYER(d) ((d & KMP3LayerMask) >> 1)
39 #define MP3_GET_BITRATE(d) ((d & KMP3BitrateMask) >> 4)
40 #define MP3_GET_SAMPLE_RATE(d) ((d & KMP3SampleRateMask) >> 2)
41 #define MP3_GET_PADDING(d) ((d & KMP3PaddingMask) >> 1)
45 // Macros used for checking various bitfields.
47 #define IS_BAD_MP3_FRAME_SYNC1(s) ((s) != 0xff)
48 #define IS_BAD_MP3_FRAME_SYNC2(s) ((s) != 0x07)
49 #define IS_BAD_MP3_VERSION(v) ((v) < 0x02)
50 #define IS_BAD_MP3_LAYER(l) ((l) == 0x00)
51 #define IS_BAD_MP3_BITRATE(b) ((b) == 0x0f)
52 #define IS_BAD_MP3_SAMPLE_RATE(s) ((s) == 0x03)
56 // Meanings of the 'Version' field.
57 // --------------------------------
58 // 00 - MPEG Version 2.5 (Unofficial standard. We don't support it.)
60 // 10 - MPEG Version 2
61 // 11 - MPEG Version 1
63 static const TInt8 KMP3Version2 = 2;
64 static const TInt8 KMP3Version1 = 3;
68 // Meanings of the 'Layer' field.
69 // ------------------------------
76 static const TUint16 KBad = 0;
77 static const TUint16 KFree = 0;
80 // MPEG Version 1 bitrates. Measured in kilobits per second.
82 static const TUint16 KBitrateVersion1[4][16] =
84 { KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad}, // Reserved layer
85 {KFree, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, KBad}, // Layer III
86 {KFree, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, KBad}, // Layer II
87 {KFree, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, KBad} // Layer I
91 // MPEG Version 2 bitrates. Measured in kilobits per second.
93 static const TUint16 KBitrateVersion2[4][16] =
95 { KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad}, // Reserved layer
96 {KFree, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, KBad}, // Layer III
97 {KFree, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, KBad}, // Layer II
98 {KFree, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, KBad} // Layer I
102 // Sample rates for the MPEG versions.
104 static const TUint16 KSampleRate[4][4] =
106 {11025, 12000, 8000, KBad}, // Version 2.5
107 { KBad, KBad, KBad, KBad}, // Reserved
108 {22050, 24000, 16000, KBad}, // Version 2
109 {44100, 48000, 32000, KBad} // Version 1
113 // Sample rates per frame for the MPEG layers.
115 static const TUint16 KSamplesPerFrame[4][4] =
117 {KBad, KBad, KBad, KBad}, // Reserved layer
118 { 576, KBad, 576, 1152}, // Layer III
119 {1152, KBad, 1152, 1152}, // Layer II
120 { 384, KBad, 384, 384} // Layer I
124 // The various states the recognition process goes through.
134 // This truth table maps the following flags to a confidence level.
135 // -----------------------------------------------------------------
138 // C: Extension recognised.
140 // A B C -> Confidence
141 // ===================
142 // 0 0 0 -> ENotRecognized
143 // 0 0 1 -> EPossible
144 // 0 1 0 -> ENotRecognized
146 // 1 0 0 -> EPossible
147 // 1 0 1 -> EProbable
148 // 1 1 0 -> EProbable
151 // In the case where two consecutive mp3 frames
152 // are found, ECertain is automatically returned.
154 static const TInt KMP3FlagsToConfidence[8] =
166 #define KMP3ConfidenceMask 0x07 // 00000111
167 #define KMP3Frame1Bit KBit1
168 #define KMP3Frame2Bit KBit2
173 TMP3Parser::TMP3Parser(CReader& aReader, TFlags& aFlags)
181 // MP3 recogition function.
183 void TMP3Parser::DoRecognise(const TDesC& aExt, CReader& aReader, TMatch& aMatch)
187 // Try to match the extension.
188 if (aExt.MatchF(TPtrC(KExtMP3)) != KErrNotFound)
190 flags.SetExtensionFlag();
194 TMP3Parser parser(aReader, flags);
195 TRAP_IGNORE(parser.ParseL());
197 TInt confIndex = flags.GetBitField(KMP3ConfidenceMask);
198 aMatch.iConfidence = KMP3FlagsToConfidence[confIndex];
199 if (aMatch.iConfidence != KConfNotRecognised)
201 aMatch.iMime = KMimeMP3;
207 // Attempts to parse an mp3 file.
208 // First of all it checks if there is an ID3 metadata header
209 // present at the current reader position. Then it checks for up to
210 // two consecutive mp3 audio frames.
212 void TMP3Parser::ParseL()
215 TMP3State state = ESearchFrame1;
219 TID3Parser::ReadAndSkipID3L(iReader);
221 TInt err = CheckForFrameHeaderL(length);
222 if (err == KErrNotFound)
230 iFlags.SetBit(KMP3Frame1Bit);
231 state = ESearchFrame2;
235 iFlags.SetBit(KMP3Frame2Bit);
239 // Skip over the audio frame.
240 // This should be done after flags have been set.
241 iReader.SeekL(length - KMP3FrameHeaderSize);
247 // Checks for an MP3 frame header at the current reader position.
248 // If one is not found KErrNotFound is returned and aFrameLength
249 // remains unchanged. If one is found KErrNone is retured and
250 // aFrameLength is set to the length of the frame.
252 TInt TMP3Parser::CheckForFrameHeaderL(TInt& aFrameLength)
254 TBuf8<KMP3FrameHeaderSize> data;
258 TUint8 sampleRateIndex;
262 data.SetLength(KMP3FrameHeaderSize);
263 iReader.ReadBytesL(data);
267 sync = MP3_GET_SYNC1(data[0]);
268 if (IS_BAD_MP3_FRAME_SYNC1(sync))
273 sync = MP3_GET_SYNC2(data[1]);
274 if (IS_BAD_MP3_FRAME_SYNC2(sync))
279 versionIndex = MP3_GET_VERSION(data[1]);
280 if (IS_BAD_MP3_VERSION(versionIndex))
285 layerIndex = MP3_GET_LAYER(data[1]);
286 if (IS_BAD_MP3_LAYER(layerIndex))
291 bitrateIndex = MP3_GET_BITRATE(data[2]);
292 if (IS_BAD_MP3_BITRATE(bitrateIndex))
297 sampleRateIndex = MP3_GET_SAMPLE_RATE(data[2]);
298 if (IS_BAD_MP3_SAMPLE_RATE(sampleRateIndex))
303 padding = MP3_GET_PADDING(data[2]);
305 // All the data is valid.
306 // Compute the audio data length.
307 TUint32 bitRate = KBad;
308 TUint16 sampleRate = KBad;
309 TUint16 samplesPerFrame = KBad;
311 if (versionIndex == KMP3Version1)
313 bitRate = KBitrateVersion1[layerIndex][bitrateIndex];
315 else if (versionIndex == KMP3Version2)
317 bitRate = KBitrateVersion2[layerIndex][bitrateIndex];
321 // Version 2.5 is not supported.
325 sampleRate = KSampleRate[versionIndex][sampleRateIndex];
326 samplesPerFrame = KSamplesPerFrame[layerIndex][versionIndex];
328 // Check we have valid values.
329 if ((bitRate == KBad) || (sampleRate == KBad) || (samplesPerFrame == KBad))
334 bitRate *= 1000; // Convert to kilobits.
335 aFrameLength = (((samplesPerFrame / KBitsPerByte) * bitRate) / sampleRate) + padding;
340 // No valid frame header was found.
342 iReader.SeekL(-KMP3FrameHeaderSize);