multimediacommscontroller/mmccamrpayloadformat/src/amrcommonutil.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccamrpayloadformat/src/amrcommonutil.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    PayloadFormat plugin capable to read RTP payload containing
+*                AMR audio.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "amrcommonutil.h"
+
+// LOCAL CONSTANTS AND MACROS
+
+// The size of AMR header, header must include bits for determining frame length
+const TInt KRawAmrFrameHeaderSize = 1;
+
+// Frame length table ( number of frame bytes )
+const TInt KRawAmrNbFrameLength[16] = { 13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1 };
+
+// Stuffing length table ( number of stuffing bits )
+const TInt KRawAmrNbStuffLength[16] = { 4, 4, 5, 5, 7, 4, 7, 7, 4,0,0,0,0,0,0,3 };
+
+// Maximum sampling rate
+const TInt KRawAmrNbMaxSampleRate = 8000; 
+
+// Maximum number of channels
+const TInt KRawAmrMaxChannels = 1;
+
+// Maximum number of PCM samples in one AMR frame
+const TInt KRawAmrNbMaxSamplesPerFrame = 160;
+
+// Frame length table ( number of frame bytes )
+const TInt KRawAmrWbFrameLength[16] = { 18,24,33,37,41,47,51,59,61,6,0,0,0,0,0,1 };
+
+// Stuffing length table ( number of stuffing bits )
+const TInt KRawAmrWbStuffLength[16] = {  4, 7, 3, 3, 3, 3, 3, 3, 3,0,0,0,0,0,0,3 };
+
+// Maximum sampling rate
+const TInt KRawAmrWbMaxSampleRate = 16000; 
+
+// Maximum number of PCM samples in one AMR-WB frame
+const TInt KRawAmrWbMaxSamplesPerFrame = 320;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAmrCommonUtility::FrameInfo
+//
+// Calculates the frame size and returns information about the frame which
+// starts from the beginning of aBuf. Returns 0, if the frame bit syntax is
+// incorrect or not enough bits are available for calculating the frame size
+// and the frame parameters ( aBufLen < TAmrCodecParams::FrameHeaderSize ).
+// 
+// The frame parameters returned via aInfo are: mode, sampling frequency,
+// number of channels, frame size ( same as return value ) and number of
+// samples in this frame.
+// -----------------------------------------------------------------------------
+//
+TInt CAmrCommonUtility::FrameInfo( const TUint8* aBuf, TInt aBufLen,
+        TAmrFrameInfo& aInfo, TBool aIsNb )
+    {
+    TInt length = 0;
+    aInfo.iBitrate = 0;
+    
+    if( aBufLen >= KRawAmrFrameHeaderSize )
+        {
+        // extract mode information
+        const TInt mode = ( aBuf[0] & 0x78 ) >> 3; // 1st byte 0b.MODE...
+        // get length
+        length =
+          ( aIsNb ? KRawAmrNbFrameLength[mode] : KRawAmrWbFrameLength[mode] );
+
+        // check start stuffing bits
+        if( ( aBuf[0] & 0x83 ) != 0 )
+            {
+            length = 0; // syntax error
+            }
+            
+        // check end stuffing bits
+        if( length > 0  &&  aBufLen >= length )
+            {
+            TUint32 stuffBits = aBuf[length-1];
+            TInt stuffLength =
+              ( aIsNb ? KRawAmrNbStuffLength[mode] : KRawAmrWbStuffLength[mode] );
+            stuffBits <<= ( KNumValue11 - stuffLength );
+            if( ( stuffBits & 0x0000FF ) != 0 )
+                {
+                length = 0; // syntax error
+                }
+            }
+
+        // update frame parameters
+        aInfo.iMode = mode;
+        // Frames are 20 ms long -> 50 frames/s. Frame length is in 8 bit bytes.
+        // Hence the number 400. This same for both nb and wb.
+        aInfo.iBitrate = length * KNumValue400;
+        aInfo.iSamplingRate =
+          ( aIsNb ? KRawAmrNbMaxSampleRate : KRawAmrWbMaxSampleRate );
+        aInfo.iChannels = KRawAmrMaxChannels;
+        aInfo.iFrameSize = length;
+        aInfo.iFrameSamples =
+          ( aIsNb ? KRawAmrNbMaxSamplesPerFrame : KRawAmrWbMaxSamplesPerFrame );
+        aInfo.iSamplingRateOut = aInfo.iSamplingRate;
+        aInfo.iChannelsOut = aInfo.iChannels;
+        aInfo.iFrameSamplesOut= aInfo.iFrameSamples;
+        }
+        
+    return length;
+    }
+
+// -----------------------------------------------------------------------------
+// CAmrCommonUtility::SeekSync
+//
+// This routine seeks the start position of the next frame and returns
+// the byte position of its header. Returns aBufLen, if no valid frame
+// can not be found ( see FrameInfo ). The seek progresses from the start
+// of aBuf ( 0 ) toward the end of aBuf( aBufLen - 1 ).
+//    
+// The level of syntax check depends on the number of bits available. At
+// minimum the first frame header bits are checked only, but if more
+// bits are available, they can be used to make the sync seek more robust.
+// For succesfull seek the whole frame does not need to exist in aBuf.
+// -----------------------------------------------------------------------------
+//
+TInt CAmrCommonUtility::SeekSync( const TUint8* aBuf, TInt aBufLen, TBool aIsNb )
+    {
+    const TInt KMaxFrames = 3;          // number of frames to check
+    const TInt KNotFound = aBufLen;     // sync not found position
+    TAmrFrameInfo frameInfo;            // frame parameters
+    
+    TInt i = 0;
+    TInt syncPos = KNotFound;
+    TInt maxSeek = KMaxFrames;
+    const TUint8* endPtr = aBuf + aBufLen;
+    
+    // Seek a valid frame candidate byte by byte until a valid frame
+    // is found or all bytes have been checked.
+    while( aBuf < endPtr && syncPos == KNotFound )
+        {
+        TInt seekCount = 0;
+        const TUint8* framePtr = aBuf;
+        TInt frameBufLen = aBufLen;
+        syncPos = i;
+        // Check the validity of this frame candidate and the nearest next
+        // frames. If they are not OK, syncPos will be set to KNotFound.
+        while( framePtr < endPtr && syncPos != KNotFound && seekCount < maxSeek )
+            {
+            TInt length = FrameInfo( framePtr, frameBufLen, frameInfo, aIsNb );
+            
+            if( frameBufLen >= KRawAmrFrameHeaderSize && length == 0 )
+                {
+                syncPos = KNotFound;
+                }
+
+            framePtr += length;
+            frameBufLen -= length;
+            seekCount++;
+            }
+            
+        aBuf++;
+        aBufLen--;
+        i++;
+        }
+        
+    return syncPos;
+    };
+
+// -----------------------------------------------------------------------------
+// CAmrCommonUtility::FrameSize
+// Returns the size of frame described by given coding parameters. The only
+// parameter used in calculation is the coding mode ( iMode ).
+// -----------------------------------------------------------------------------
+//
+TInt CAmrCommonUtility::FrameSize( const TAmrFrameInfo& aInfo, TBool aIsNb )
+    {
+    if ( aIsNb )
+        {
+        return KRawAmrNbFrameLength[ aInfo.iMode ];
+        }
+    else        
+        {
+        return KRawAmrWbFrameLength[ aInfo.iMode ];
+        }
+    };
+
+// -----------------------------------------------------------------------------
+// CAmrCommonUtility::FrameHeaderSize
+// Returns the size of one AMR frame header in bytes. The header must include
+// all bits needed for determining the actual frame length.
+// -----------------------------------------------------------------------------
+//
+TInt CAmrCommonUtility::FrameHeaderSize( )
+    {
+    return KRawAmrFrameHeaderSize; 
+    };
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+//  End of File  
+