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.
16 #include "constants.h"
19 // The length of the frame in written directly into the header.
20 // It is 13 bits in length and spans 3 bytes.
22 #define AAC_SYNC1_MASK 0xff // 11111111
23 #define AAC_SYNC2_MASK 0xf0 // 11110000
24 #define AAC_FRAME_LENGTH_MASK1 0x03 // 00000011
25 #define AAC_FRAME_LENGTH_MASK2 0xff // 11111111
26 #define AAC_FRAME_LENGTH_MASK3 0xe0 // 11100000
27 #define AAC_LAYER_MASK 0x06 // 00000110
29 #define AAC_GET_SYNC1(d) (d)
30 #define AAC_GET_SYNC2(d) ((d & AAC_SYNC2_MASK) >> 4)
31 #define AAC_GET_LAYER(d) (((d) & AAC_LAYER_MASK) >> 1)
32 #define AAC_GET_FRAME_LENGTH(a, b, c) \
33 (((a) & AAC_FRAME_LENGTH_MASK1) << 11) | \
34 (((b) & AAC_FRAME_LENGTH_MASK2) << 03) | \
35 (((c) & AAC_FRAME_LENGTH_MASK3) >> 05)
38 #define AAC_IS_BAD_SYNC1(s) ((s) != 0xff)
39 #define AAC_IS_BAD_SYNC2(s) ((s) != 0x0f)
40 #define AAC_IS_BAD_LAYER(l) ((l) != 0x00)
41 #define AAC_IS_BAD_FRAME_LENGTH(l) ((l) < KAACFrameHeaderSize)
44 // The various states the recognition process goes through.
54 // This truth table maps the following flags to a confidence level.
56 // A: Extension identified.
60 // C B A -> Confidence
61 // ===================
62 // 0 0 0 -> ENotRecognised
66 // 1 0 0 -> ENotRecognised (Can't have f2 without f1)
67 // 1 0 1 -> ENotRecognised (Can't have f2 without f1)
71 static const TInt KAACFlagsToConfidence[8] =
83 #define KAACConfidenceMask 0x07 // [0000 0111]
84 #define KAACFrame1Bit KBit1
85 #define KAACFrame2Bit KBit2
90 // Constructs a TAACParser on the stack.
92 TAACParser::TAACParser(CReader& aReader, TFlags& aFlags)
102 void TAACParser::DoRecognise(const TDesC& aFileExt, CReader& aReader, TMatch& aMatch)
107 // See if the extension is recognised.
108 extMatch = (aFileExt.MatchF(TPtrC(KExtAAC)) != KErrNotFound);
110 // Try to match a known header.
111 if (aReader.Match(TPtrC8(_S8("ADIF*"))))
113 aMatch.iConfidence = (extMatch ? KConfCertain : KConfProbable);
114 aMatch.iMime = KMimeAAC;
118 // No known header so try to parse it.
119 // Parsing uses flags to track what has been identified.
122 flags.SetExtensionFlag();
125 TAACParser parser(aReader, flags);
126 TRAP_IGNORE(parser.ParseL());
128 TInt confIndex = flags.GetBitField(KAACConfidenceMask);
129 aMatch.iConfidence = KAACFlagsToConfidence[confIndex];
130 if (aMatch.iConfidence != KConfNotRecognised)
132 aMatch.iMime = KMimeAAC;
138 // Looks for valid AAC frame headers; at the current position
139 // and immediately after (if one found).
141 void TAACParser::ParseL()
144 TAACState state = ESearchFrame1;
146 // Check if it's an ADTS (raw) format AAC file.
147 // There's no known metadata tag for AAC so the
148 // first frame header should be at the start of the buffer.
152 TID3Parser::ReadAndSkipID3L(iReader);
154 TInt err = CheckForFrameHeaderL(frameLength);
155 if (err == KErrNotFound)
163 iFlags.SetBit(KAACFrame1Bit);
164 state = ESearchFrame2;
168 iFlags.SetBit(KAACFrame2Bit);
172 // Skip over the audio frame.
173 // This should be done after flags have been set.
174 iReader.SeekL(frameLength - KAACFrameHeaderSize);
180 // Looks for valid AAC frame header bit patterns.
181 // If one is not found KErrNotFound is returned and aFrameLength
182 // remains unchanged. If one is found KErrNone is retured and
183 // aFrameLength is set to the length of the frame.
185 TInt TAACParser::CheckForFrameHeaderL(TInt& aFrameLength)
187 TBuf8<KAACFrameHeaderSize> header;
189 header.SetLength(KAACFrameHeaderSize);
190 iReader.ReadBytesL(header);
194 if (AAC_IS_BAD_SYNC1(AAC_GET_SYNC1(header[0])))
199 if (AAC_IS_BAD_SYNC2(AAC_GET_SYNC2(header[1])))
204 if (AAC_IS_BAD_LAYER(AAC_GET_LAYER(header[1])))
209 TInt frameLength = AAC_GET_FRAME_LENGTH(header[3], header[4], header[5]);
210 if (AAC_IS_BAD_FRAME_LENGTH(frameLength))
215 aFrameLength = frameLength;
220 // No frame header was found.
222 iReader.SeekL(-KAACFrameHeaderSize);