diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccamrpayloadformat/src/amrcommonutil.cpp --- /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 +