mmlibs/mmfw/Recogniser/src/mp3parser.cpp
author hgs
Tue, 02 Nov 2010 12:28:51 +0000
changeset 6 fe9d1bf55678
parent 0 b8ed18f6c07b
permissions -rw-r--r--
2010wk46_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     2
// All rights reserved.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     7
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     8
// Initial Contributors:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    10
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    11
// Contributors:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    12
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    13
// Description:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    14
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    15
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    16
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    17
#include "parsers.h"
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    18
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    19
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    20
// Masks used for reading bits.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    21
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    22
static const TInt KMP3Sync1Mask = 0xff;			// 11111111
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    23
static const TInt KMP3Sync2Mask = 0xe0;			// 11100000
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    24
static const TInt KMP3VersionMask = 0x18;		// 00011000
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    25
static const TInt KMP3LayerMask = 0x06;			// 00000110
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    26
static const TInt KMP3BitrateMask = 0xf0;		// 11110000
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    27
static const TInt KMP3SampleRateMask = 0x0c;	// 00001100
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    28
static const TInt KMP3PaddingMask = 0x02;		// 00000010
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    29
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    30
static const TInt KBitsPerByte = 8;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    31
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    32
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    33
// Macros for retrieving the values.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    34
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    35
#define MP3_GET_SYNC1(d)				(d & KMP3Sync1Mask)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    36
#define MP3_GET_SYNC2(d)				((d & KMP3Sync2Mask) >> 5)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    37
#define MP3_GET_VERSION(d)				((d & KMP3VersionMask) >> 3)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    38
#define MP3_GET_LAYER(d)				((d & KMP3LayerMask) >> 1)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    39
#define MP3_GET_BITRATE(d)				((d & KMP3BitrateMask) >> 4)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    40
#define MP3_GET_SAMPLE_RATE(d)			((d & KMP3SampleRateMask) >> 2)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    41
#define MP3_GET_PADDING(d)				((d & KMP3PaddingMask) >> 1)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    42
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    43
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    44
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    45
// Macros used for checking various bitfields.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    46
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    47
#define IS_BAD_MP3_FRAME_SYNC1(s)		((s) != 0xff)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    48
#define IS_BAD_MP3_FRAME_SYNC2(s)		((s) != 0x07)	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    49
#define IS_BAD_MP3_VERSION(v)			((v) <  0x02)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    50
#define IS_BAD_MP3_LAYER(l)				((l) == 0x00) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    51
#define IS_BAD_MP3_BITRATE(b)			((b) == 0x0f)	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    52
#define IS_BAD_MP3_SAMPLE_RATE(s)		((s) == 0x03)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    53
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    54
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    55
// 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    56
// Meanings of the 'Version' field.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    57
// --------------------------------
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    58
// 00 - MPEG Version 2.5 (Unofficial standard. We don't support it.)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    59
// 01 - Reserved
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    60
// 10 - MPEG Version 2
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    61
// 11 - MPEG Version 1
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    62
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    63
static const TInt8 KMP3Version2 = 2;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    64
static const TInt8 KMP3Version1 = 3;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    65
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    66
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    67
// 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    68
// Meanings of the 'Layer' field.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    69
// ------------------------------
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    70
// 00 - Reserved
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    71
// 01 - Layer III
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    72
// 10 - Layer II
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    73
// 11 - Layer I
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    74
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    75
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    76
static const TUint16 KBad = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    77
static const TUint16 KFree = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    78
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    79
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    80
// MPEG Version 1 bitrates. Measured in kilobits per second.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    81
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    82
static const TUint16 KBitrateVersion1[4][16] =
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    83
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    84
	{ KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad}, // Reserved layer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    85
	{KFree,   32,   40,   48,   56,   64,   80,   96,  112,  128,  160,  192,  224,  256,  320, KBad}, // Layer III
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    86
	{KFree,   32,   48,   56,   64,   80,   96,  112,  128,  160,  192,  224,  256,  320,  384, KBad}, // Layer II
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    87
	{KFree,   32,   64,   96,  128,  160,  192,  224,  256,  288,  320,  352,  384,  416,  448, KBad}  // Layer I
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    88
	};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    89
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    90
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    91
// MPEG Version 2 bitrates. Measured in kilobits per second.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    92
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    93
static const TUint16 KBitrateVersion2[4][16] =
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    94
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    95
	{ KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad, KBad}, // Reserved layer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    96
	{KFree,    8,   16,   24,   32,   40,   48,   56,   64,   80,   96,  112,  128,  144,  160, KBad}, // Layer III 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    97
	{KFree,    8,   16,   24,   32,   40,   48,   56,   64,   80,   96,  112,  128,  144,  160, KBad}, // Layer II
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    98
	{KFree,   32,   48,   56,   64,   80,   96,  112,  128,  144,  160,  176,  192,  224,  256, KBad}  // Layer I
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    99
	};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   100
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   101
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   102
// Sample rates for the MPEG versions.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   103
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   104
static const TUint16 KSampleRate[4][4] = 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   105
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   106
		{11025, 12000,  8000, KBad}, // Version 2.5
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   107
		{ KBad,  KBad,  KBad, KBad}, // Reserved
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   108
		{22050, 24000, 16000, KBad}, // Version 2
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   109
		{44100, 48000, 32000, KBad}  // Version 1
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   110
	};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   111
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   112
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   113
// Sample rates per frame for the MPEG layers.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   114
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   115
static const TUint16 KSamplesPerFrame[4][4] = 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   116
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   117
		{KBad, KBad, KBad, KBad}, // Reserved layer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   118
		{ 576, KBad,  576, 1152}, // Layer III
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   119
		{1152, KBad, 1152, 1152}, // Layer II
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   120
		{ 384, KBad,  384,  384}  // Layer I
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   121
	};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   122
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   123
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   124
// The various states the recognition process goes through.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   125
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   126
typedef enum
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   127
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   128
	ESearchFrame1,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   129
	ESearchFrame2
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   130
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   131
TMP3State;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   132
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   133
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   134
// This truth table maps the following flags to a confidence level.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   135
// -----------------------------------------------------------------
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   136
// A: Frame2 found.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   137
// B: Frame1 found.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   138
// C: Extension recognised.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   139
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   140
// A B C -> Confidence
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   141
// ===================
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   142
// 0 0 0 -> ENotRecognized
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   143
// 0 0 1 -> EPossible
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   144
// 0 1 0 -> ENotRecognized
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   145
// 0 1 1 -> ECertain
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   146
// 1 0 0 -> EPossible
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   147
// 1 0 1 -> EProbable
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   148
// 1 1 0 -> EProbable
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   149
// 1 1 1 -> ECertain
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   150
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   151
// In the case where two consecutive mp3 frames
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   152
// are found, ECertain is automatically returned.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   153
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   154
static const TInt KMP3FlagsToConfidence[8] = 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   155
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   156
	KConfNotRecognised,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   157
	KConfPossible,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   158
	KConfNotRecognised,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   159
	KConfCertain,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   160
	KConfPossible,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   161
	KConfProbable,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   162
	KConfProbable,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   163
	KConfCertain
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   164
	};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   165
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   166
#define KMP3ConfidenceMask	0x07	// 00000111
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   167
#define KMP3Frame1Bit		KBit1
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   168
#define KMP3Frame2Bit		KBit2
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   169
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   170
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   171
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   172
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   173
TMP3Parser::TMP3Parser(CReader& aReader, TFlags& aFlags)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   174
 : 	iReader(aReader),
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   175
 	iFlags(aFlags)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   176
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   177
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   178
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   179
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   180
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   181
// MP3 recogition function.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   182
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   183
void TMP3Parser::DoRecognise(const TDesC& aExt, CReader& aReader, TMatch& aMatch)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   184
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   185
	TFlags flags;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   186
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   187
	// Try to match the extension.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   188
	if (aExt.MatchF(TPtrC(KExtMP3)) != KErrNotFound)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   189
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   190
		flags.SetExtensionFlag();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   191
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   192
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   193
	// Parse the data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   194
	TMP3Parser parser(aReader, flags);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   195
	TRAP_IGNORE(parser.ParseL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   196
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   197
	TInt confIndex = flags.GetBitField(KMP3ConfidenceMask);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   198
	aMatch.iConfidence = KMP3FlagsToConfidence[confIndex];
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   199
	if (aMatch.iConfidence != KConfNotRecognised)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   200
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   201
		aMatch.iMime = KMimeMP3;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   202
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   203
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   204
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   205
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   206
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   207
// Attempts to parse an mp3 file.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   208
// First of all it checks if there is an ID3 metadata header
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   209
// present at the current reader position. Then it checks for up to
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   210
// two consecutive mp3 audio frames.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   211
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   212
void TMP3Parser::ParseL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   213
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   214
	TInt length;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   215
	TMP3State state = ESearchFrame1;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   216
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   217
	FOREVER
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   218
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   219
		TID3Parser::ReadAndSkipID3L(iReader);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   220
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   221
		TInt err = CheckForFrameHeaderL(length);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   222
		if (err == KErrNotFound)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   223
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   224
			return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   225
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   226
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   227
		switch (state)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   228
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   229
			case ESearchFrame1:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   230
				iFlags.SetBit(KMP3Frame1Bit);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   231
				state = ESearchFrame2;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   232
				break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   233
					
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   234
			case ESearchFrame2:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   235
				iFlags.SetBit(KMP3Frame2Bit);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   236
				return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   237
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   238
				
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   239
		// Skip over the audio frame.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   240
		// This should be done after flags have been set.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   241
		iReader.SeekL(length - KMP3FrameHeaderSize);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   242
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   243
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   244
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   245
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   246
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   247
// Checks for an MP3 frame header at the current reader position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   248
// If one is not found KErrNotFound is returned and aFrameLength
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   249
// remains unchanged. If one is found KErrNone is retured and
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   250
// aFrameLength is set to the length of the frame.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   251
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   252
TInt TMP3Parser::CheckForFrameHeaderL(TInt& aFrameLength)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   253
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   254
	TBuf8<KMP3FrameHeaderSize> data;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   255
	TUint8 versionIndex;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   256
	TUint8 layerIndex;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   257
	TUint8 bitrateIndex;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   258
	TUint8 sampleRateIndex;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   259
	TUint8 padding;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   260
	TUint8 sync;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   261
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   262
	data.SetLength(KMP3FrameHeaderSize);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   263
	iReader.ReadBytesL(data);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   264
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   265
	do
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   266
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   267
		sync = MP3_GET_SYNC1(data[0]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   268
		if (IS_BAD_MP3_FRAME_SYNC1(sync))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   269
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   270
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   271
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   272
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   273
		sync = MP3_GET_SYNC2(data[1]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   274
		if (IS_BAD_MP3_FRAME_SYNC2(sync))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   275
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   276
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   277
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   278
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   279
		versionIndex = MP3_GET_VERSION(data[1]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   280
		if (IS_BAD_MP3_VERSION(versionIndex))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   281
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   282
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   283
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   284
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   285
		layerIndex = MP3_GET_LAYER(data[1]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   286
		if (IS_BAD_MP3_LAYER(layerIndex))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   287
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   288
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   289
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   290
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   291
		bitrateIndex = MP3_GET_BITRATE(data[2]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   292
		if (IS_BAD_MP3_BITRATE(bitrateIndex))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   293
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   294
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   295
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   296
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   297
		sampleRateIndex = MP3_GET_SAMPLE_RATE(data[2]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   298
		if (IS_BAD_MP3_SAMPLE_RATE(sampleRateIndex))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   299
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   300
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   301
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   302
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   303
		padding = MP3_GET_PADDING(data[2]);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   304
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   305
		// All the data is valid.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   306
		// Compute the audio data length.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   307
		TUint32 bitRate = KBad;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   308
		TUint16 sampleRate = KBad;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   309
		TUint16 samplesPerFrame = KBad;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   310
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   311
		if (versionIndex == KMP3Version1)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   312
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   313
			bitRate = KBitrateVersion1[layerIndex][bitrateIndex];
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   314
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   315
		else if (versionIndex == KMP3Version2)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   316
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   317
			bitRate = KBitrateVersion2[layerIndex][bitrateIndex];
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   318
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   319
		else 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   320
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   321
			// Version 2.5 is not supported.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   322
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   323
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   324
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   325
		sampleRate = KSampleRate[versionIndex][sampleRateIndex];
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   326
		samplesPerFrame = KSamplesPerFrame[layerIndex][versionIndex];
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   327
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   328
		// Check we have valid values.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   329
		if ((bitRate == KBad) || (sampleRate == KBad) || (samplesPerFrame == KBad))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   330
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   331
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   332
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   333
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   334
		bitRate *= 1000; // Convert to kilobits.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   335
		aFrameLength = (((samplesPerFrame / KBitsPerByte) * bitRate) / sampleRate) + padding;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   336
		return KErrNone;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   337
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   338
	while (EFalse);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   339
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   340
	// No valid frame header was found.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   341
	aFrameLength = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   342
	iReader.SeekL(-KMP3FrameHeaderSize);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   343
	return KErrNotFound;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   344
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   345
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   346
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   347
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   348