mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/mp3audioplaycontroller/Src/MP3AudioPlayControllerHwDecoder.cpp
changeset 0 71ca22bcf22a
child 12 5a06f39ad45b
child 18 2eb3b066cc7d
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  The functions in this module implements the specific behavior
       
    15 *                for the advanced audio converter class for configuration of
       
    16 *				 hardware accelerated codec.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "MP3AudioPlayControllerDecoder.h"
       
    23 #include "DebugMacros.h"
       
    24 #include <MmfPanicCodes.h>
       
    25 #include <Mmfcodec.h>
       
    26 
       
    27 const TUint KRawMp3MaxFrameSize  = 1441;
       
    28 const TUint KSizeOfInBuffer   = 2*KRawMp3MaxFrameSize;
       
    29 const TInt 	KRawMp3FrameHeaderSize = 5;
       
    30 
       
    31 class TAudioFrameInfo
       
    32     {
       
    33 	public:
       
    34 		TInt iMode;            // encoding mode
       
    35 		TInt iBitRate;         // bitrate (bit/s)
       
    36 		TInt iSamplingRate;    // sampling frequency (Hz)
       
    37 		TInt iChannels;        // number of channels
       
    38 		TInt iFrameSize;       // encoded size (bytes)
       
    39 		TInt iFrameSamples;    // samples per frame
       
    40 		TInt iSamplingRateOut; // sampling frequency after conversion (Hz)
       
    41 		TInt iChannelsOut;     // number of audio channels after conversion (1 or 2)
       
    42 		TInt iFrameSamplesOut; // decoded size after conversion (samples per frame)
       
    43 		TInt iPadding;         // padding flag (TRUE or FALSE, TRUE if p slot exists)
       
    44 		TInt iId;              // id of algorithm (1 MPEG-1, 0 MPEG-2)
       
    45     };
       
    46     
       
    47 // Bit rates in bits/sec supported by MPEG2, MPEG1 and MPEG2.5 respectively
       
    48 const TInt16 cBitRateTable[3][16] =
       
    49 	{
       
    50 		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
       
    51 		{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0},
       
    52 		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
       
    53 	};
       
    54 
       
    55 // Sampling frequencies supported by MPEG2, MPEG1 and MPEG2.5 respectively
       
    56 const TUint16 cSamplingFrequencyTable[3][4] =
       
    57 	{
       
    58 		{22050,24000,16000,0},
       
    59 		{44100,48000,32000,0},
       
    60 		{11025,12000,8000,0},
       
    61 	};
       
    62 
       
    63 // ============================ MEMBER FUNCTIONS ===============================
       
    64 
       
    65 // -----------------------------------------------------------------------------
       
    66 // C++ default constructor can NOT contain any code, that
       
    67 // might leave.
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 CMP3AudioPlayControllerDecoder::CMP3AudioPlayControllerDecoder()
       
    71     :   CAdvancedAudioDecoder(CActive::EPriorityStandard)
       
    72     {
       
    73     DP0(_L("CMP3AudioPlayControllerDecoder::CMP3AudioPlayControllerDecoder - Hardware Accelerated"));
       
    74     iMaxFrameSize = KRawMp3MaxFrameSize;
       
    75    	iSizeOfInBuffer = KSizeOfInBuffer;
       
    76     }
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // CMP3AudioPlayControllerDecoder::ConstructL
       
    80 // Symbian 2nd phase constructor can leave.
       
    81 // -----------------------------------------------------------------------------
       
    82 //
       
    83 void CMP3AudioPlayControllerDecoder::ConstructL()
       
    84     {
       
    85     DP1(_L("CMP3AudioPlayControllerDecoder::ConstructL"), this);
       
    86 
       
    87     iFrameTable = CFrameTable::NewL();
       
    88     
       
    89 	RenderEnable();
       
    90 	UnMarkPlayEnd();
       
    91 	Enable();
       
    92     
       
    93     CActiveScheduler::Add(this);
       
    94     }
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // C++ default constructor can NOT contain any code, that
       
    98 // might leave.
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 CMP3AudioPlayControllerDecoder* CMP3AudioPlayControllerDecoder::NewL()
       
   102     {
       
   103     DP0(_L("CMP3AudioPlayControllerDecoder::NewL"));
       
   104 
       
   105     CMP3AudioPlayControllerDecoder* self = new(ELeave) CMP3AudioPlayControllerDecoder();
       
   106     CleanupStack::PushL(self);
       
   107     self->ConstructL();
       
   108     CleanupStack::Pop(self);
       
   109     return self;
       
   110     }
       
   111 
       
   112 // Destructor
       
   113 CMP3AudioPlayControllerDecoder::~CMP3AudioPlayControllerDecoder()
       
   114 	{
       
   115     DP0(_L("CMP3AudioPlayControllerDecoder::~CMP3AudioPlayControllerDecoder"));
       
   116     delete iFrameTable;
       
   117 	}
       
   118 
       
   119 TInt CMP3AudioPlayControllerDecoder::CodecConfig(RArray<TInt>& aConfigData)
       
   120 	{
       
   121 	TInt status = KErrNone;
       
   122 	TInt sampFreq = ((RArray<TInt>&) aConfigData)[5];
       
   123 	TInt samplesPerFrame = ((RArray<TInt>&) aConfigData)[8];
       
   124 	iFrameTable->InitFrameTable(sampFreq, samplesPerFrame);
       
   125 	return status;
       
   126 	}
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CMP3AudioPlayControllerDecoder::ResetL
       
   130 // Resets configuration data and configures the codec.
       
   131 // -----------------------------------------------------------------------------
       
   132 //
       
   133 void CMP3AudioPlayControllerDecoder::ResetL()
       
   134 	{
       
   135     DP0(_L ("CMP3AudioPlayControllerDecoder::Reset - Enter"));
       
   136 
       
   137 	delete[] iOutBuffer;
       
   138    	delete[] iInBuffer;
       
   139    	
       
   140    	iInBuffer = NULL;
       
   141    	iOutBuffer = NULL;
       
   142    	iInBufferCount = 0;
       
   143    	iOutBufferCount = 0;
       
   144    	iOutBufferPtr = NULL;
       
   145    	iOutFrameLength = KRawMp3MaxFrameSize; // since data is not decoded
       
   146    	iInBuffer = new (ELeave) TUint8[KSizeOfInBuffer];
       
   147 
       
   148     iOutBuffer = new (ELeave) TUint8[iOutFrameLength];
       
   149     iOutBufferPtr = iOutBuffer;
       
   150 
       
   151     iAccLen = 0;
       
   152     iEnabled = ETrue; 
       
   153     DP0(_L ("CMP3AudioPlayControllerDecoder::Reset - Exit"));
       
   154 	}
       
   155 
       
   156 TCodecProcessResult CMP3AudioPlayControllerDecoder::ProcessL(CMMFBuffer& aSrc, CMMFBuffer& aDst)
       
   157 	{
       
   158     DP0(_L ("CMP3AudioPlayControllerDecoder::ProcessL"));
       
   159 	return CAdvancedAudioDecoder::ProcessHwL(aSrc, aDst);
       
   160 	}
       
   161 
       
   162 TInt CMP3AudioPlayControllerDecoder::FrameLength(const TUint8* aBuf, TInt aBufLen, TInt& aFrameLength)
       
   163 	{
       
   164 	TInt stat = KErrNone;
       
   165 	TAudioFrameInfo info;
       
   166 	TInt len = FrameInfo(aBuf, aBufLen, info);
       
   167 	if (len > 0)
       
   168 		{
       
   169 		aFrameLength = len;
       
   170 		}
       
   171 	else
       
   172 		{
       
   173 		stat = KErrUnknown;
       
   174 		}
       
   175 	return stat;
       
   176 	}
       
   177 	
       
   178 // -----------------------------------------------------------------------------
       
   179 // CMP3AudioPlayControllerDecoder::FrameInfo
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 TInt CMP3AudioPlayControllerDecoder::FrameInfo(
       
   183 	const TUint8* aBuf,
       
   184 	TInt aBufLen,
       
   185 	TAudioFrameInfo& aInfo)
       
   186     {
       
   187     TInt length = 0;
       
   188     TUint temp;
       
   189     TUint lTempVal;
       
   190 
       
   191 	if (aBufLen >= KRawMp3FrameHeaderSize)
       
   192 	    {
       
   193 		// Extract header fields to aInfo and check their bit syntax
       
   194 		// (including the sync word!). If the syntax is not OK the length
       
   195 		// is set to zero.
       
   196 
       
   197 		temp = 0;
       
   198 		temp = aBuf[0] << 24;
       
   199 		temp |= (aBuf[1] << 16);
       
   200 		temp |= (aBuf[2] << 8);
       
   201 		temp |= aBuf[3];
       
   202 		if (((temp >> 21) & 0x7FF) != 0x7FF)
       
   203 			{
       
   204 			return length;
       
   205 			}
       
   206 
       
   207 		lTempVal = (temp >> 19) & 0x03;
       
   208 		switch (lTempVal)
       
   209 			{
       
   210 			case 0:
       
   211 				aInfo.iId = 2;  // MPEG2.5
       
   212 				aInfo.iFrameSamples = 576;
       
   213 				break;
       
   214 			case 1:
       
   215 				return length;
       
   216 			case 2:
       
   217 				aInfo.iId = 0;  // MPEG 2
       
   218 				aInfo.iFrameSamples = 576;
       
   219 				break;
       
   220 			case 3:
       
   221 				aInfo.iId = 1;  // MPEG 1
       
   222 				aInfo.iFrameSamples = 1152;
       
   223 				break;
       
   224 			}
       
   225 
       
   226 		lTempVal = (temp >> 17) & 0x03;
       
   227 		if (lTempVal != 1)
       
   228 			{
       
   229 			return length;
       
   230 			}
       
   231 
       
   232 		lTempVal = (temp >> 12) & 0x0F;
       
   233 		aInfo.iBitRate = cBitRateTable[aInfo.iId][lTempVal]*1000;
       
   234 
       
   235 		if (aInfo.iBitRate == 0)
       
   236 			{
       
   237 			return length;
       
   238 			}
       
   239 
       
   240 		lTempVal = (temp >> 10) & 0x03;
       
   241 		if (lTempVal == 3)
       
   242 			{
       
   243 			return length;
       
   244 			}
       
   245 		else
       
   246 			{
       
   247 			aInfo.iSamplingRate = cSamplingFrequencyTable[aInfo.iId][lTempVal];
       
   248 			}
       
   249 
       
   250 		aInfo.iPadding = (temp >> 9) & 0x01;
       
   251 
       
   252 		lTempVal = (temp >> 6) & 0x03;
       
   253 		aInfo.iMode = lTempVal;
       
   254 
       
   255 		if (lTempVal == 3)
       
   256 			{
       
   257 			aInfo.iChannels = 1;
       
   258 			}
       
   259 		else
       
   260             {
       
   261             aInfo.iChannels = 2;
       
   262             }
       
   263 
       
   264         aInfo.iSamplingRateOut = aInfo.iSamplingRate;
       
   265         aInfo.iChannelsOut = 2; /* always set to stereo output */
       
   266         aInfo.iFrameSamplesOut = aInfo.iFrameSamples;
       
   267 
       
   268 		if (aInfo.iBitRate == -1)
       
   269 			{
       
   270 			// For free mode operation
       
   271 			length = KRawMp3MaxFrameSize;
       
   272 			}
       
   273 
       
   274 		if (aInfo.iSamplingRate > 0  &&  aInfo.iBitRate > 0)
       
   275 			{
       
   276 			length = (144*aInfo.iBitRate)/aInfo.iSamplingRate;
       
   277 
       
   278 			if (aInfo.iId != 1)
       
   279 				{
       
   280 				length >>= 1; /*for MPEG2 and MPEG2.5 */
       
   281 				}
       
   282 
       
   283 			if (aInfo.iPadding)
       
   284 				{
       
   285 				length++;
       
   286 				}
       
   287 			}
       
   288 
       
   289 		aInfo.iFrameSize = length;
       
   290 //        iChannelsOut = aInfo.iChannelsOut;
       
   291     	}
       
   292     return length;
       
   293     }
       
   294 
       
   295 // -----------------------------------------------------------------------------
       
   296 // CMP3AudioPlayControllerDecoder::SeekSync
       
   297 // -----------------------------------------------------------------------------
       
   298 TInt CMP3AudioPlayControllerDecoder::SeekSync(TUint8* aBuf, TInt aBufLen)
       
   299     {
       
   300     const TInt KMaxFrames = 3;          // number of frames to check
       
   301     const TInt KNotFound = aBufLen;     // sync not found position
       
   302     TAudioFrameInfo frameInfo;           // frame parameters
       
   303     TInt i = 0;
       
   304     TInt syncPos = KNotFound;
       
   305     TInt maxSeek = KMaxFrames;
       
   306     const TUint8* endPtr = aBuf+aBufLen;
       
   307 
       
   308     // Seek a valid frame candidate byte by byte until a valid frame
       
   309     // is found or all bytes have been checked.
       
   310     while (aBuf < endPtr  &&  syncPos == KNotFound)
       
   311 	    {
       
   312         TInt seekCount = 0;
       
   313         const TUint8* framePtr = aBuf;
       
   314         TInt frameBufLen = aBufLen;
       
   315         syncPos = i;
       
   316 
       
   317 		// Check the validity of this frame candidate and the nearest next
       
   318         // frames. If they are not OK, syncPos will be set to KNotFound.
       
   319         while (framePtr < endPtr  &&  syncPos != KNotFound  && seekCount < maxSeek)
       
   320 	        {
       
   321             TInt length = FrameInfo(framePtr, frameBufLen, frameInfo);
       
   322 
       
   323 			if (length == 0)
       
   324             	{
       
   325                 syncPos = KNotFound;
       
   326 				}
       
   327             if ((length > 0) && (frameInfo.iBitRate < 0))
       
   328             	{
       
   329                 maxSeek = 1; // free formatcase
       
   330 				}
       
   331             framePtr += length;
       
   332             frameBufLen -= length;
       
   333             seekCount++;
       
   334 
       
   335 			// consider SYNC not found if we reach end of buffer before finding 3 SYNC frames
       
   336 			if ((framePtr >= endPtr) && (seekCount < maxSeek))
       
   337 				{
       
   338 				syncPos = KNotFound;
       
   339 				aBuf += (aBufLen-1);      // force an exit from while loop
       
   340 				}
       
   341         	}
       
   342         aBuf++; aBufLen--; i++;
       
   343     	}
       
   344     return syncPos;
       
   345     }
       
   346 
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 // CMP3AudioPlayControllerDecoder::IsHwAccelerated
       
   350 // Always return true when no soft codec is used.
       
   351 // -----------------------------------------------------------------------------
       
   352 //
       
   353 TBool CMP3AudioPlayControllerDecoder::IsHwAccelerated()
       
   354 	{
       
   355 	return ETrue;
       
   356 	}
       
   357 
       
   358 TInt CMP3AudioPlayControllerDecoder::CodecCmd(TCodecCmd /*aCmd*/)
       
   359 	{
       
   360 	return KErrNotSupported;
       
   361 	}
       
   362 
       
   363 
       
   364 // End of file