mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioControllerUtility/Src/AWBAudioControllerUtility.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 AWB utility functions.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDES
       
    20 #include "AWBAudioControllerUtility.h"
       
    21 #include <mmfdatabuffer.h>
       
    22 #include "DebugMacros.h"
       
    23 
       
    24 // CONSTANTS
       
    25 _LIT8(KAwbMagicNumber,"#!AMR-WB\n");
       
    26 
       
    27 // The size of AMR WB header, header must include bits for determining frame length
       
    28 const TInt KRawAwbFrameHeaderSize = 1;
       
    29 
       
    30 // Frame length table (number of frame bytes)
       
    31 const TInt KRawAwbFrameLength[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61,
       
    32                                         6, 6, 0, 0, 0, 1, 1};
       
    33 // Stuffing length table (number of stuffing bits)
       
    34 const TInt KRawAwbStuffLength[16] = {7, 10, 6, 6, 6, 6, 6, 6, 6,3,3,0,0,0,3,3};
       
    35 
       
    36 // Maximum sampling rate
       
    37 const TInt KRawAwbMaxSampleRate = 16000;
       
    38 
       
    39 // Maximum number of channels
       
    40 const TInt KRawAwbMaxChannels = 1;
       
    41 
       
    42 // Maximum number of PCM samples in one AMR WB frame
       
    43 const TInt KRawAwbMaxSamplesPerFrame = 320;
       
    44 
       
    45 // constant time for each frame = 0.020 sec
       
    46 const TInt KAwbMilliSecondsPerFrame  = 20;
       
    47 
       
    48 const TInt KAwbSampleRate = 16000;
       
    49 const TInt KAwbBitRate = 7200;
       
    50 const TInt KAwbChannels = 1;
       
    51 
       
    52 // ============================ MEMBER FUNCTIONS ===============================
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CAWBAudioControllerUtility::CAWBAudioControllerUtility
       
    56 // C++ default constructor can NOT contain any code, that
       
    57 // might leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CAWBAudioControllerUtility::CAWBAudioControllerUtility()
       
    61     {
       
    62 	iSamplingRate = KAwbSampleRate;
       
    63 	iChannels = KAwbChannels;
       
    64 	iBitRate = KAwbBitRate;
       
    65 	iHeaderOffset = KAwbMagicNumber().Size();
       
    66 	iFrameTimeMs = KAwbMilliSecondsPerFrame;
       
    67     iLenMetaData = 0;
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CAWBAudioControllerUtility::ConstructL
       
    72 // Symbian 2nd phase constructor can leave.
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 void CAWBAudioControllerUtility::ConstructL()
       
    76     {
       
    77 	iPosArr = new(ELeave) CArrayFixSeg<TTimePos>(1024);
       
    78 	}
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CAWBAudioControllerUtility::NewL
       
    82 // Two-phased constructor.
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 EXPORT_C CAWBAudioControllerUtility* CAWBAudioControllerUtility::NewL()
       
    86 	{
       
    87     DP0(_L("CAWBAudioControllerUtility::NewL"));
       
    88     CAWBAudioControllerUtility* self = new(ELeave) CAWBAudioControllerUtility;
       
    89     CleanupStack::PushL(self);
       
    90     self->ConstructL();
       
    91     CleanupStack::Pop(self);
       
    92     return self;
       
    93     }
       
    94 
       
    95 // Destructor
       
    96 EXPORT_C CAWBAudioControllerUtility::~CAWBAudioControllerUtility()
       
    97     {
       
    98 	iPosArr->Reset();
       
    99 	delete iPosArr;
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CAWBAudioControllerUtility::SeekSync
       
   104 // -----------------------------------------------------------------------------
       
   105 //
       
   106 TInt CAWBAudioControllerUtility::SeekSync(
       
   107 	CMMFDataBuffer* aBuf,
       
   108 	TInt aBufLen)
       
   109     {
       
   110     const TUint8* buf = aBuf->Data().Ptr();
       
   111     const TInt KMaxFrames = 3;          // number of frames to check
       
   112     const TInt KNotFound = aBufLen;     // sync not found position
       
   113     TAudioFrameInfo frameInfo;            // frame parameters
       
   114     TInt i = 0;
       
   115     TInt syncPos = KNotFound;
       
   116     TInt maxSeek = KMaxFrames;
       
   117     const TUint8* endPtr = buf + aBufLen;
       
   118 
       
   119     // Seek a valid frame candidate byte by byte until a valid frame
       
   120     // is found or all bytes have been checked.
       
   121     while (buf < endPtr  &&  syncPos == KNotFound)
       
   122 		{
       
   123         TInt seekCount = 0;
       
   124         const TUint8* framePtr = buf;
       
   125         TInt frameBufLen = aBufLen;
       
   126         syncPos = i;
       
   127         // Check the validity of this frame candidate and the nearest next
       
   128         // frames. If they are not OK, syncPos will be set to KNotFound.
       
   129         while (framePtr < endPtr  &&  syncPos != KNotFound  &&  seekCount < maxSeek)
       
   130 			{
       
   131             TInt length = FrameInfo(framePtr, frameBufLen, frameInfo);
       
   132             if (frameBufLen >= KRawAwbFrameHeaderSize  &&  length == 0)
       
   133             	{
       
   134 				syncPos = KNotFound;
       
   135 				}
       
   136             framePtr += length;
       
   137             frameBufLen -= length;
       
   138             seekCount++;
       
   139 			}
       
   140         buf++; aBufLen--; i++;
       
   141 		}
       
   142     return syncPos;
       
   143     }
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CAWBAudioControllerUtility::FrameInfo
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 TInt CAWBAudioControllerUtility::FrameInfo(
       
   150 	const TUint8* aBuf,
       
   151 	TInt aBufLen,
       
   152 	TAudioFrameInfo& aInfo)
       
   153     {
       
   154     TInt length = 0;
       
   155     aInfo.iBitRate = 0;
       
   156     if (aBufLen >= KRawAwbFrameHeaderSize)
       
   157     	{
       
   158         // extract mode information
       
   159         const TInt mode = (aBuf[0] & 0x78) >> 3; // 1st byte 0b.MODE...
       
   160         // get length
       
   161         length = KRawAwbFrameLength[mode];
       
   162 
       
   163         // check start stuffing bits
       
   164         if((aBuf[0] & 0x83) != 0)
       
   165 			{
       
   166             length = 0; // syntax error
       
   167 			}
       
   168 
       
   169         // check end stuffing bits
       
   170         if (length > 0  &&  aBufLen >= length)
       
   171 			{
       
   172             TUint32 stuffBits = aBuf[length-1];
       
   173             stuffBits <<= (11 - KRawAwbStuffLength[mode]);
       
   174             if ((stuffBits & 0x0000FF) != 0)
       
   175 				{
       
   176                 length = 0; // syntax error
       
   177 				}
       
   178 			}
       
   179 
       
   180         // update frame parameters
       
   181         aInfo.iMode = mode;
       
   182         aInfo.iBitRate = length * 400;
       
   183         aInfo.iSamplingRate = KRawAwbMaxSampleRate;
       
   184         aInfo.iChannels = KRawAwbMaxChannels;
       
   185         aInfo.iFrameSize = length;
       
   186         aInfo.iFrameSamples = KRawAwbMaxSamplesPerFrame;
       
   187         aInfo.iSamplingRateOut = aInfo.iSamplingRate;
       
   188         aInfo.iChannelsOut = aInfo.iChannels;
       
   189         aInfo.iFrameSamplesOut= aInfo.iFrameSamples;
       
   190 		}
       
   191     return length;
       
   192     }
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CAWBAudioControllerUtility::FrameHeaderSize
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 TInt CAWBAudioControllerUtility::FrameHeaderSize()
       
   199     {
       
   200     return KRawAwbFrameHeaderSize;
       
   201     }
       
   202 
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CMP3AudioControllerUtility::ScanHeaderL
       
   206 // Used to scan the header information
       
   207 // -----------------------------------------------------------------------------
       
   208 //
       
   209 void CAWBAudioControllerUtility::ScanHeaderL(
       
   210 	CMMFDataBuffer* aDataBuf)
       
   211 	{
       
   212 	DP0(_L("CAMRAudioControllerUtility::ScanHeaderL"));
       
   213 	iBitRateFrozen = EFalse; // AMR does not have bitrate in container header, so it will be averaged while playing
       
   214     const TUint8* bufferPtr = aDataBuf->Data().Ptr();
       
   215     TInt bufferSize = aDataBuf->Data().Size();
       
   216 	
       
   217 	TInt scannedBuffer = 0;
       
   218 	
       
   219     if (iLenMetaData == 0)
       
   220         {
       
   221         iSyncOffset = 0;
       
   222         iLenMetaData = ID3HeaderLength(aDataBuf);
       
   223         }
       
   224 
       
   225     TInt bufferRemaining = bufferSize;
       
   226     
       
   227     while (iLenMetaData > 0)
       
   228         {
       
   229 	    if (iLenMetaData >= bufferRemaining)
       
   230 	        {
       
   231 	        // this buffer contain no frame
       
   232 	        iSyncOffset += bufferRemaining;
       
   233 	        iLenMetaData -= bufferRemaining;
       
   234 	        User::Leave(KErrNotReady);
       
   235 	        }
       
   236 	    else
       
   237 	        {
       
   238 	        iSyncOffset += iLenMetaData;
       
   239 	        scannedBuffer += iLenMetaData;
       
   240 	        // be sure to check for following id3 tags
       
   241 	        bufferRemaining = bufferSize - scannedBuffer;
       
   242 	        aDataBuf->SetPosition(scannedBuffer);
       
   243 	        iLenMetaData = ID3HeaderLength(aDataBuf);
       
   244     	    }
       
   245         }
       
   246 
       
   247     aDataBuf->SetPosition(scannedBuffer);
       
   248 	TInt seekOffset = SeekSync(aDataBuf, bufferSize);
       
   249 	TInt realOffset = seekOffset - scannedBuffer; // we just want offset from where we were
       
   250 
       
   251 	iHeaderOffset = 0;
       
   252 	if (realOffset >= 9)
       
   253 		{
       
   254 		bufferPtr = aDataBuf->Data().Ptr() + seekOffset - 9;
       
   255    		TUint32* w1p = (TUint32*)bufferPtr;
       
   256    		TUint32* w2p = (TUint32*)(bufferPtr+4);
       
   257    		TUint8*  w3p = (TUint8*)(bufferPtr+8);
       
   258     	if (((*w1p & 0x4D412123)==0x4D412123) && 
       
   259     		((*w2p & 0x42572D52)==0x42572D52) &&
       
   260     		((*w3p & 0x0A)==0x0A))
       
   261     		{
       
   262 			iHeaderOffset = 9;
       
   263 			realOffset -= 9;
       
   264     		}
       
   265 		else if (seekOffset == aDataBuf->Data().Size())
       
   266 			{
       
   267 			User::Leave(KErrNotReady);
       
   268 			}	
       
   269 		}
       
   270 
       
   271     iSyncOffset += realOffset; // offset to this point from content beginning
       
   272     scannedBuffer += realOffset + iHeaderOffset; // offset to this point in this buffer
       
   273 	bufferPtr = aDataBuf->Data().Ptr();
       
   274     aDataBuf->SetPosition(scannedBuffer);
       
   275     
       
   276 	DP0(_L("CAWBAudioControllerUtility::ScanHeaderL - Calling FrameInfo"));
       
   277 
       
   278 	TAudioFrameInfo frameInfo;
       
   279 	TInt frameLen = FrameInfo(bufferPtr+scannedBuffer, bufferSize-scannedBuffer, frameInfo);
       
   280 
       
   281 	if (frameLen == 0)
       
   282 		{
       
   283 	    User::Leave(KErrNotReady);
       
   284 		}
       
   285 		
       
   286 //	scannedBuffer += frameLen;
       
   287     iBitRate = 0;
       
   288     iDurationUs = 0;
       
   289 	
       
   290     iSamplingRate = frameInfo.iSamplingRate;
       
   291     iBitRate = frameInfo.iBitRate;
       
   292     iSamplesPerFrame = frameInfo.iFrameSamples;
       
   293     iChannels = frameInfo.iChannels;
       
   294     iChannelsOut = frameInfo.iChannelsOut;
       
   295 //	iSamplingRateOut = frameInfo.iSamplingRateOut;
       
   296 
       
   297 	if (iSamplingRate > 0)
       
   298 	    {
       
   299     	iFrameTimeMs = (iSamplesPerFrame*1000)/iSamplingRate;
       
   300 	    }
       
   301 	    
       
   302 	TInt frameBytes = 0;
       
   303 	TInt avgFrameLen = 0;
       
   304 	TInt frames = 0;
       
   305 	for (TInt i=1; i<=100; i++)
       
   306 		{
       
   307 		if (scannedBuffer > bufferSize)
       
   308 			{
       
   309 			break;
       
   310 			}
       
   311 		frameLen = FrameInfo(bufferPtr+scannedBuffer, bufferSize-scannedBuffer, frameInfo);
       
   312 		scannedBuffer += frameLen;
       
   313 		if (frameLen <= 0)
       
   314 			{
       
   315 			break;
       
   316 			}
       
   317 		if (i == 10) // ignore the first 10 frames
       
   318 			{
       
   319 			frameBytes = frameLen;
       
   320 			frames = 1;    	        	
       
   321 			}
       
   322 		else
       
   323 			{
       
   324 			frameBytes += frameLen;
       
   325 			frames++;    	        	
       
   326 			}	
       
   327 		avgFrameLen = frameBytes / frames; // frames is always non-zero here
       
   328 		}
       
   329 	iBitRate = (avgFrameLen * 8 * iSamplingRate) / iSamplesPerFrame;
       
   330 	}
       
   331 
       
   332 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   333 
       
   334 // End of File
       
   335