diff -r 000000000000 -r 79dd3e2336a0 devsound/devsoundrefplugin/src/plugin/audio/Gsm610/GSM610.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/devsound/devsoundrefplugin/src/plugin/audio/Gsm610/GSM610.CPP Fri Oct 08 19:40:43 2010 +0100 @@ -0,0 +1,442 @@ +// Copyright (c) 2002-2010 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: +// * INCLUDE FILES: +// +// + +// Standard includes +#include +#include + +#include +#include "GSM610.H" +#include +#include +#include +#include + +/** +* +* NewL +* @return CMmfGsm610ToPcm16HwDevice* +* +*/ +CMmfGsm610ToPcm16HwDevice* CMmfGsm610ToPcm16HwDevice::NewL() + { + CMmfGsm610ToPcm16HwDevice* self=new(ELeave) CMmfGsm610ToPcm16HwDevice(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +* +* Codec +* +*/ +CMMFSwCodec& CMmfGsm610ToPcm16HwDevice::Codec() + { + return *iCodec; + } + +/** +* +* CMmfGsm610ToPcm16HwDevice +* +*/ +CMmfGsm610ToPcm16HwDevice::~CMmfGsm610ToPcm16HwDevice() + { + } + + +/** +* +* ConstructL +* +*/ +void CMmfGsm610ToPcm16HwDevice::ConstructL() + { + CMMFGsm610ToPcm16Codec* ptr= new(ELeave)CMMFGsm610ToPcm16Codec(); + CleanupStack::PushL(ptr); + ptr->ConstructL(); + iCodec = ptr; + CleanupStack::Pop(ptr); + } + +/** +* +* CMmfPcm16ToGsm610HwDevice +* +*/ +CMmfPcm16ToGsm610HwDevice* CMmfPcm16ToGsm610HwDevice::NewL() + { + CMmfPcm16ToGsm610HwDevice* self=new(ELeave) CMmfPcm16ToGsm610HwDevice(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +* +* Codec +* @return CMMFSwCodec& +* +*/ +CMMFSwCodec& CMmfPcm16ToGsm610HwDevice::Codec() + { + return *iCodec; + } + +/** +* +* ~CMmfPcm16ToGsm610HwDevice +* +*/ +CMmfPcm16ToGsm610HwDevice::~CMmfPcm16ToGsm610HwDevice() + { + } + +/** +* +* ConstructL +* +*/ +void CMmfPcm16ToGsm610HwDevice::ConstructL() + { + CMMFPcm16ToGsm610Codec* ptr =new(ELeave) CMMFPcm16ToGsm610Codec(); + CleanupStack::PushL(ptr); + ptr->ConstructL(); + iCodec = ptr; + CleanupStack::Pop(ptr); + } + +/** +* +* CMMFGsm610ToPcm16Codec +* +*/ +CMMFGsm610ToPcm16Codec::CMMFGsm610ToPcm16Codec() + { + } + +/** +* +* ConstructL +* +*/ +void CMMFGsm610ToPcm16Codec::ConstructL() + { + iGsmDecoder = GSM610FR_DecoderFactory::CreateDecoderL(); + iGsmDecoder->StartL(); + } + +/** +* +* NewL +* +*/ +CMMFGsm610ToPcm16Codec* CMMFGsm610ToPcm16Codec::NewL() + { + CMMFGsm610ToPcm16Codec* self=new(ELeave) CMMFGsm610ToPcm16Codec(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +* +* ~CMMFGsm610ToPcm16Codec +* +*/ +CMMFGsm610ToPcm16Codec::~CMMFGsm610ToPcm16Codec() + { + if(iGsmDecoder) + { + iGsmDecoder->Release(); + } + } + +/** +* +* ProcessL +* @param aSource +* @param aDest +* @precondition input buffer length is mod 65 +* @precondition output buffer has sufficient space for coded input +* +*/ +CMMFSwCodec::TCodecProcessResult CMMFGsm610ToPcm16Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDest) + { + CMMFSwCodec::TCodecProcessResult result; + result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete; + + //convert from generic CMMFBuffer to CMMFDataBuffer + CMMFBuffer* pSrcBuffer =const_cast(&aSrc); + if( !pSrcBuffer ) + { + User::Leave( KErrArgument ); + } + + CMMFDataBuffer* src = static_cast( pSrcBuffer ); + if( !src ) + { + User::Leave( KErrArgument ); + } + + CMMFDataBuffer* dst = static_cast(&aDest); + if( !dst ) + { + User::Leave( KErrArgument ); + } + + if(!CheckInputBuffers( *src, *dst )) + { + User::Leave( KErrArgument ); + } + + TInt numBuffersToProcess = NumBuffersToProcess( *src ); + TUint8* pSrc = CONST_CAST(TUint8*,src->Data().Ptr()); + TUint8* pDst = CONST_CAST(TUint8*,dst->Data().Ptr()); + + for( TInt count = 0; count < numBuffersToProcess; count++ ) + { + // Encode two frames of gsm data + iGsmDecoder->ExecuteL( pSrc, pDst ); + pSrc += KGsmFrameSize;; + pDst += KPcmDataForGsmFrame; + result.iSrcBytesProcessed += KGsmFrameSize; + result.iDstBytesAdded += KPcmDataForGsmFrame; + } + + dst->Data().SetLength( result.iDstBytesAdded ); + __ASSERT_DEBUG( ProcessPostCondition( result ), TMmfGsmCodecPanicsNameSpace::Panic( TMmfGsmCodecPanicsNameSpace::EPostConditionViolation )); + return result; + } + +/** +* +* CheckInputBuffers +* @param aSrc +* @param aDest +* @return TBool +* This function returns ETrue if the preconditions of processL are met +* +*/ +TBool CMMFGsm610ToPcm16Codec::CheckInputBuffers( CMMFDataBuffer& aSrc, CMMFDataBuffer& aDest ) + { + TBool result = ETrue; + TInt numInputSubFrames = aSrc.Data().Length() / KGsmFrameSize; + TInt numOutputSubFrames = aDest.Data().MaxLength() / KPcmDataForGsmFrame; + TBool validInputDataLength = (aSrc.Data().Length() % KGsmFrameSize == 0) ? ETrue : aSrc.LastBuffer(); + + if( (numInputSubFrames > numOutputSubFrames) || // sufficient space in the output for the input + (aSrc.Position() > 0 ) || // position must be zero since we can eat all the data + (aDest.Position() > 0 ) || + (!validInputDataLength)) //position must be zero + { + result = EFalse; + } + + return result; + } + +/** +* +* NumBuffersToProcess +* @param aSrc +* @return TBool +* This method returns the number of buffers to process +* +*/ +TInt CMMFGsm610ToPcm16Codec::NumBuffersToProcess( const CMMFDataBuffer& aSrc ) + { + TInt numBuffers = (aSrc.Data().Length() / KGsmFrameSize ); + return numBuffers; + } + +/** +* +* ProcessPostCondition +* @param aResult +* @result TBool Etrue if the post condition is satisfied +* +**/ +TBool CMMFGsm610ToPcm16Codec::ProcessPostCondition( const CMMFSwCodec::TCodecProcessResult& aResult ) + { + TBool status = ETrue; + if( (aResult.iSrcBytesProcessed / KGsmFrameSize ) != (aResult.iDstBytesAdded / KPcmDataForGsmFrame ) ) + { + status = EFalse; + } + return status; + } + +/************************>----------------------------------<*****************************/ + +/** +* +* CMMFPcm16ToGsm610Codec +* +*/ +CMMFPcm16ToGsm610Codec::CMMFPcm16ToGsm610Codec() + { + } + +/** +* +* ConstructL +* +*/ +void CMMFPcm16ToGsm610Codec::ConstructL() + { + iGsmEncoder = GSM610FR_EncoderFactory::CreateEncoderL(); + iGsmEncoder->StartL(); + } + +/** +* +* NewL +* +*/ +CMMFPcm16ToGsm610Codec* CMMFPcm16ToGsm610Codec::NewL() + { + CMMFPcm16ToGsm610Codec* self=new(ELeave) CMMFPcm16ToGsm610Codec(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +* +* CMMFPcm16ToGsm610Codec +* +*/ +CMMFPcm16ToGsm610Codec::~CMMFPcm16ToGsm610Codec() + { + if(iGsmEncoder) + { + iGsmEncoder->Release(); + } + } + +/** +* +* ProcessL +* @param aSource +* @param aDest TCodecProcessResult +* @result +* @precondition input buffer length is mod 320 +* @precondition output buffer has sufficient space for coded input +*/ +CMMFSwCodec::TCodecProcessResult CMMFPcm16ToGsm610Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDest) + { + CMMFSwCodec::TCodecProcessResult result; + result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete; + + //convert from generic CMMFBuffer to CMMFDataBuffer + CMMFBuffer* pSrcBuffer =const_cast(&aSrc); + if( !pSrcBuffer ) + { + User::Leave( KErrArgument ); + } + + CMMFDataBuffer* src = static_cast( pSrcBuffer ); + if( !src ) + { + User::Leave( KErrArgument ); + } + + CMMFDataBuffer* dst = static_cast(&aDest); + if( !dst ) + { + User::Leave( KErrArgument ); + } + + + if(!CheckInputBuffers( *src, *dst )) + { + User::Leave( KErrArgument ); + } + + TInt numBuffersToProcess = NumBuffersToProcess( *src ); + TUint8* pSrc = CONST_CAST(TUint8*,src->Data().Ptr()); + TUint8* pDst = CONST_CAST(TUint8*,dst->Data().Ptr()); + + for( TInt count = 0; count < numBuffersToProcess; count++ ) + { + // Encode two frames of gsm data + iGsmEncoder->ExecuteL (pSrc, pDst); + pSrc += KPcmDataForGsmFrame; + pDst += KGsmFrameSize; + result.iSrcBytesProcessed += KPcmDataForGsmFrame; + result.iDstBytesAdded += KGsmFrameSize; + } + + dst->Data().SetLength( result.iDstBytesAdded ); + + __ASSERT_DEBUG( ProcessPostCondition(result), TMmfGsmCodecPanicsNameSpace::Panic( TMmfGsmCodecPanicsNameSpace::EPostConditionViolation )); + + return result ; + } + +/** +* +* CheckInputBuffers +* @param aSrc +* @param aDest +* @return TBool +* This function returns ETrue if there is sufficient space +* in the output buffer for the coded input and +* the position of both input buffers is zero +* +*/ +TBool CMMFPcm16ToGsm610Codec::CheckInputBuffers( CMMFDataBuffer& aSrc, CMMFDataBuffer& aDest ) + { + TBool result = ETrue; + TInt numInputSubFrames = aSrc.Data().Length() / KPcmDataForGsmFrame; + TInt numOutputSubFrames = aDest.Data().MaxLength() / KGsmFrameSize; +#ifdef EABI + TBool validInputDataLength = (aSrc.Data().Length() % KPcmDataForGsmFrame == 0); +#else + TBool validInputDataLength = (aSrc.LastBuffer()? ETrue: (aSrc.Data().Length() % KPcmDataForGsmFrame == 0)); +#endif + if( (numInputSubFrames > numOutputSubFrames) || // sufficient space in the output for the input + (aSrc.Position() > 0 ) || // position must be zero since we can eat all the data + (aDest.Position() > 0 ) || + (!validInputDataLength)) //position must be zero + { + result = EFalse; + } + + return result; + } + +/** +* +* NumBuffersToProcess +* @param aSrc +* @return TBool +* This method returns the number of buffers to process +* +*/ +TInt CMMFPcm16ToGsm610Codec::NumBuffersToProcess( const CMMFDataBuffer& aSrc ) + { + TInt numBuffers = ( aSrc.Data().Length() / KPcmDataForGsmFrame ); + return numBuffers; + } +