mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioControllerUtility/Src/EAACPlusAudioControllerUtility.cpp
changeset 0 71ca22bcf22a
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:  Class definition for the AAC utility functions.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDES
       
    20 #include "EAACPlusAudioControllerUtility.h"
       
    21 #include "DebugMacros.h"
       
    22 #include <e32svr.h>                             //For Debug
       
    23 #include <mmfdatabuffer.h>
       
    24 
       
    25 // CONSTANTS
       
    26 //const TInt KAdtsNumFramesToScan = 500;
       
    27 //const TInt KAdifNumFramesToScan = 200;
       
    28 //const TInt KMaxAacFrameSize     = 1536;
       
    29 
       
    30 // ============================ MEMBER FUNCTIONS ===============================
       
    31 
       
    32 // -----------------------------------------------------------------------------
       
    33 // CEAACPlusAudioControllerUtility::CEAACPlusAudioControllerUtility
       
    34 // C++ default constructor can NOT contain any code, that
       
    35 // might leave.
       
    36 // -----------------------------------------------------------------------------
       
    37 //
       
    38 CEAACPlusAudioControllerUtility::CEAACPlusAudioControllerUtility()
       
    39     {
       
    40     }
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CEAACPlusAudioControllerUtility::ConstructL
       
    44 // Symbian 2nd phase constructor can leave.
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 void CEAACPlusAudioControllerUtility::ConstructL()
       
    48     {
       
    49 	DP0(_L("CEAACPlusAudioControllerUtility::ConstructL"));
       
    50 
       
    51 	iAacUtil = CEAacPlusUtil::NewL();
       
    52     }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CEAACPlusAudioControllerUtility::NewL
       
    56 // Two-phased constructor.
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 EXPORT_C CEAACPlusAudioControllerUtility* CEAACPlusAudioControllerUtility::NewL()
       
    60 	{
       
    61 	DP0(_L("CEAACPlusAudioControllerUtility::NewL"));
       
    62 
       
    63     CEAACPlusAudioControllerUtility* self = new(ELeave) CEAACPlusAudioControllerUtility;
       
    64     CleanupStack::PushL(self);
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop(self);
       
    67     return self;
       
    68     }
       
    69 
       
    70 // Destructor
       
    71 EXPORT_C CEAACPlusAudioControllerUtility::~CEAACPlusAudioControllerUtility()
       
    72     {
       
    73 	delete iAacUtil;
       
    74     }
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // CEAACPlusAudioControllerUtility::PrependHeader
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 EXPORT_C TBool CEAACPlusAudioControllerUtility::PrependHeader()
       
    81     { // not needed
       
    82 	DP0(_L("CEAACPlusAudioControllerUtility::PrependHeader"));
       
    83 
       
    84     return (iFormatType == CEAacPlusUtil::EAacPlusFormatAdif) ? ETrue : EFalse;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CEAACPlusAudioControllerUtility::ScanHeaderL
       
    89 // Used to scan the header information
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 void CEAACPlusAudioControllerUtility::ScanHeaderL(
       
    93 	CMMFDataBuffer* aDataBuf)
       
    94 	{
       
    95 	DP0(_L("CEAACPlusAudioControllerUtility::ScanHeaderL"));
       
    96 
       
    97     const TUint8* bufferPtr = aDataBuf->Data().Ptr();
       
    98     TInt bufferSize = aDataBuf->Data().Size();
       
    99 	
       
   100 	TInt scannedBuffer = 0;
       
   101 	iBitRateFrozen = EFalse;
       
   102 	
       
   103     if (iLenMetaData == 0)
       
   104         {
       
   105         iSyncOffset = 0;
       
   106         iLenMetaData = ID3HeaderLength(aDataBuf);
       
   107         }
       
   108 
       
   109     TInt bufferRemaining = bufferSize;
       
   110 
       
   111     while (iLenMetaData > 0)
       
   112         {
       
   113 	    if (iLenMetaData >= bufferRemaining)
       
   114 	        {
       
   115 	        // this buffer contain no frame
       
   116 	        iSyncOffset += bufferRemaining;
       
   117 	        iLenMetaData -= bufferRemaining;
       
   118 	        User::Leave(KErrNotReady);
       
   119 	        }
       
   120 	    else
       
   121 	        {
       
   122 	        iSyncOffset += iLenMetaData;
       
   123 	        scannedBuffer += iLenMetaData;
       
   124 	        // be sure to check for following id3 tags
       
   125 	        bufferRemaining = bufferSize - scannedBuffer;
       
   126 	        aDataBuf->SetPosition(scannedBuffer);
       
   127 	        iLenMetaData = ID3HeaderLength(aDataBuf);
       
   128     	    }
       
   129         }
       
   130 
       
   131 
       
   132     TInt seekOffset = 0;
       
   133     aDataBuf->SetPosition(scannedBuffer);
       
   134 	seekOffset = SeekSync(aDataBuf, aDataBuf->Data().Size());
       
   135 	
       
   136     iSyncOffset += seekOffset; // offset to this point from content beginning
       
   137     scannedBuffer += seekOffset; // offset to this point in this buffer
       
   138     aDataBuf->SetPosition(scannedBuffer);
       
   139     
       
   140 	if (seekOffset == aDataBuf->Data().Size())
       
   141 		{
       
   142 		User::Leave(KErrNotReady);
       
   143 		}
       
   144 
       
   145 //    iSyncOffset += seekOffset; // offset to this point from content beginning
       
   146 //    scannedBuffer += seekOffset; // offset to this point in this buffer
       
   147 //    aDataBuf->SetPosition(scannedBuffer);
       
   148     
       
   149 	DP0(_L("CEAACPlusAudioControllerUtility::ScanHeaderL - Calling FrameInfo"));
       
   150 
       
   151     CEAacPlusUtil::TEAacPlusFrameInfo frameInfo;
       
   152     TInt hdrLen = bufferSize-scannedBuffer;
       
   153     
       
   154     TInt status = iAacUtil->GetAacFrameInfo(bufferPtr+scannedBuffer, hdrLen, frameInfo);
       
   155 
       
   156     iOutFrameSize = frameInfo.iOutFrameSize;
       
   157     iSamplesPerFrame = frameInfo.iNoOfSamples;
       
   158     iSamplingFrequency = frameInfo.iSamplingFrequency;
       
   159     iChannels = frameInfo.iNoOfChannels;
       
   160     iChannelsOut = frameInfo.iNoOfChannels; // util should set this to 2 if PS is present
       
   161     iProfile = frameInfo.iObjectType-1; // convert from object type back to what decoder uses 
       
   162     iOutSamplingFrequency = frameInfo.iOutSamplingFrequency;
       
   163     iDownSampledMode = frameInfo.iDownSampledMode;
       
   164 
       
   165     iExtObjectType = 0;
       
   166 	if (frameInfo.iSbr)
       
   167 		{
       
   168 		iExtObjectType = 5;
       
   169 // ??????????????? double-check this - if this is done, dsm should also have to be enabled
       
   170 //        if (iOutSamplingFrequency > 48000)
       
   171 //        	iSamplingRate = iOutSamplingFrequency/2;
       
   172 //        else
       
   173 //        	iSamplingRate = iOutSamplingFrequency;
       
   174 		}
       
   175 //	else    // For Regular AAC Files
       
   176 //    	{
       
   177         iSamplingRate = iOutSamplingFrequency;
       
   178 //    	}
       
   179 	if (frameInfo.iPs)
       
   180 	    {
       
   181 	    iExtObjectType = 6;
       
   182 	    }
       
   183 
       
   184 	status = iAacUtil->GetAacFormatType(bufferPtr+scannedBuffer, bufferSize-scannedBuffer, iFormatType);
       
   185 
       
   186 	iHeaderOffset = 0;
       
   187     iBitRate = 0;
       
   188     iDurationUs = 0;
       
   189     TInt frameLen = 0;
       
   190     
       
   191 	switch (iFormatType)
       
   192 		{
       
   193 		case CEAacPlusUtil::EAacPlusFormatAdif:
       
   194             iHeaderOffset = hdrLen;
       
   195             iBitRate = GetBitrate(aDataBuf);
       
   196 			if (iBitRate != 0)
       
   197 				{ // if we can read bitrate from the header, then use it from now on
       
   198 				DP1(_L("CEAACPlusAudioControllerUtility::ScanHeaderL freezing bitrate [%d]"), iBitRate);
       
   199 				iBitRateFrozen = ETrue;
       
   200 				break;
       
   201 				}
       
   202 			scannedBuffer += iHeaderOffset;	
       
   203 
       
   204 		case CEAacPlusUtil::EAacPlusFormatAdts:
       
   205 		case CEAacPlusUtil::EAacPlusFormatRaw:
       
   206 			{
       
   207 //        	status = iAacUtil->GetAacFrameLength(bufferPtr+scannedBuffer, bufferSize-scannedBuffer, frameLen);
       
   208 //        	// don't use first frame in averaging below, it may be short
       
   209 //	        if (frameLen <= 0)
       
   210 //	            { // don't event try to calculate bitrate
       
   211 //	            frameLen = 0;
       
   212 //	            break;
       
   213 //	            }
       
   214 	
       
   215 	        TInt frameBytes = 0;
       
   216 	        TInt avgFrameLen = 0;
       
   217 	        TInt frames = 0;
       
   218 //            scannedBuffer += frameLen;
       
   219             for (TInt i=1; i<=100; i++)
       
   220                 {
       
   221                 if (scannedBuffer > bufferSize)
       
   222                     {
       
   223                     break;
       
   224                     }
       
   225     	        status = iAacUtil->GetAacFrameLength(bufferPtr+scannedBuffer, bufferSize-scannedBuffer, frameLen);
       
   226                 scannedBuffer += frameLen;
       
   227     	        if (frameLen <= 0)
       
   228     	            {
       
   229     	            break;
       
   230     	            }
       
   231 //    	        if (frameLen > (avgFrameLen << 1))
       
   232     	        if (i == 10) // ignore the first 10 frames
       
   233     	        	{
       
   234 	    	        frameBytes = frameLen;
       
   235 					frames = 1;    	        	
       
   236     	        	}
       
   237     	        else
       
   238     	        	{
       
   239 	    	        frameBytes += frameLen;
       
   240 					frames++;    	        	
       
   241     	        	}	
       
   242     	        avgFrameLen = frameBytes / frames; // frames is always non-zero here
       
   243                 }
       
   244             iBitRate = (avgFrameLen * 8 * iSamplingFrequency) / iSamplesPerFrame;
       
   245 			break;
       
   246 			}
       
   247 		default:
       
   248 			User::Leave(KErrNotSupported);
       
   249 			break;
       
   250 		}
       
   251     }
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CEAACPlusAudioControllerUtility::SeekSync
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 TInt CEAACPlusAudioControllerUtility::SeekSync(
       
   258 	CMMFDataBuffer* aBuf, TInt aBufLen)
       
   259 	{ // should return aBufLen if not found
       
   260 	DP0(_L("CEAACPlusAudioControllerUtility::SeekSync"));
       
   261     const TUint8* buf = aBuf->Data().Ptr() + aBuf->Position();
       
   262     TInt bufLen = aBufLen - aBuf->Position();
       
   263 
       
   264     const TInt KNotFound = aBufLen;     // sync not found position
       
   265     TInt syncPos = KNotFound;
       
   266     TInt seekLen = 0;
       
   267     
       
   268     while (seekLen < bufLen)
       
   269         {
       
   270         if (IsValidAacFrame(buf + seekLen, bufLen - seekLen))
       
   271         	{
       
   272         	syncPos = seekLen;
       
   273             break;
       
   274 			}
       
   275         seekLen++;
       
   276         }
       
   277     return syncPos;
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CEAACPlusAudioControllerUtility::SetCodecConfigData
       
   282 // -----------------------------------------------------------------------------
       
   283 // This is really a get, not a set
       
   284 void CEAACPlusAudioControllerUtility::SetCodecConfigData(
       
   285 	RArray<TInt>& aCodecConfig)
       
   286     {
       
   287     aCodecConfig[0]  = iSamplingRate;
       
   288     aCodecConfig[1]  = iChannels;
       
   289     aCodecConfig[2]  = iProfile;
       
   290     aCodecConfig[3]  = iOutFrameSize;
       
   291     aCodecConfig[4]  = iSamplesPerFrame;
       
   292     aCodecConfig[5]  = iSamplingFrequency;
       
   293     aCodecConfig[7]  = iDownSampledMode;
       
   294     aCodecConfig[9]  = iOutSamplingFrequency;
       
   295     aCodecConfig[10] = iExtObjectType;
       
   296     aCodecConfig[12] = iFormatType; // this is only available after scan header
       
   297 	}
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CEAACPlusAudioControllerUtility::GetBitrate
       
   301 // -----------------------------------------------------------------------------
       
   302 //
       
   303 TInt CEAACPlusAudioControllerUtility::GetBitrate(CMMFDataBuffer* aBuffer)
       
   304     {
       
   305     const TUint8* ptr = aBuffer->Data().Ptr();
       
   306     TInt offset = 4;            // "ADIF"
       
   307     TInt bitrate = 0;
       
   308     
       
   309     offset += aBuffer->Position();
       
   310     
       
   311     if (ptr[offset] >> 7 == 1)  // copyright
       
   312         offset += 9;
       
   313 
       
   314     bitrate = ptr[offset] & 0x7;                    // 4 bits
       
   315     bitrate = (bitrate << 8) | ptr[offset+1];       // 8 bits
       
   316     bitrate = (bitrate << 8) | ptr[offset+2];       // 8 bits
       
   317     bitrate = (bitrate << 3) | ptr[offset+3] >> 5;  // 3 bits
       
   318     return bitrate;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CEAACPlusAudioControllerUtility::IsValidAacFrame
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 TBool CEAACPlusAudioControllerUtility::IsValidAacFrame(
       
   326 	const TUint8* aPtr,	TInt aBufLen)
       
   327     {
       
   328 	DP0(_L("CEAACPlusAudioControllerUtility::IsValidAacFrame"));
       
   329 
       
   330 	if (aBufLen >= 4)
       
   331 		{
       
   332 		if ((aPtr[0] == 'A') && (aPtr[1] == 'D') && (aPtr[2] == 'I') && (aPtr[3] == 'F'))
       
   333 			return ETrue;
       
   334 		}
       
   335 
       
   336 	if (aBufLen >= 6)
       
   337 		{
       
   338 		if (((aPtr[0] == 0xFF) && ((aPtr[1] >> 4) == 0xF) &&    // Check syncword FFF
       
   339     	     ((aPtr[1] >> 1) & 0x3) == 0))                      // Check layer == 0
       
   340 	        {
       
   341     	    TInt frameLen = 0;
       
   342 	        frameLen = (aPtr[3] & 0x3) << 11;
       
   343     	    frameLen |= aPtr[4] << 3;
       
   344         	frameLen |= ((aPtr[5] >> 5) & 0x7);
       
   345 
       
   346 	        if (!frameLen || (frameLen > (aBufLen-4))) // check this for correctness
       
   347     	       return EFalse;
       
   348 
       
   349 	        // Check next frame
       
   350 	        if (aBufLen - frameLen >= 2)
       
   351 	        	{
       
   352 	    	    const TUint8* nextFramePtr = aPtr + frameLen;
       
   353 		    	if ((((nextFramePtr[0] == 0xFF) && ((nextFramePtr[1] >> 4) == 0xF)) && // Check syncword FFF
       
   354 	    	         ((nextFramePtr[1] >> 1) & 0x3) == 0)) // Check layer == 0
       
   355 	    	        {
       
   356     	    	    return ETrue;
       
   357 	    	        }
       
   358 	        	}
       
   359         	}
       
   360 		}
       
   361 
       
   362     return EFalse;
       
   363     }
       
   364 
       
   365 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   366 
       
   367 // End of File
       
   368