sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // * INCLUDE FILES: sl@0: // sl@0: // sl@0: sl@0: // Standard includes sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: #include "BtGsm610.h" sl@0: #include "gsm610fr.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include "../../../MmfBtFileDependencyUtil.h" sl@0: sl@0: /** sl@0: * sl@0: * NewL sl@0: * @return CMmfGsm610ToPcm16HwDevice* sl@0: * sl@0: */ sl@0: CMmfGsm610ToPcm16HwDevice* CMmfGsm610ToPcm16HwDevice::NewL() sl@0: { sl@0: CMmfGsm610ToPcm16HwDevice* self=new(ELeave) CMmfGsm610ToPcm16HwDevice(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Codec sl@0: * sl@0: */ sl@0: CMMFSwCodec& CMmfGsm610ToPcm16HwDevice::Codec() sl@0: { sl@0: return *iCodec; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CMmfGsm610ToPcm16HwDevice sl@0: * sl@0: */ sl@0: CMmfGsm610ToPcm16HwDevice::~CMmfGsm610ToPcm16HwDevice() sl@0: { sl@0: } sl@0: sl@0: sl@0: /** sl@0: * sl@0: * ConstructL sl@0: * sl@0: */ sl@0: void CMmfGsm610ToPcm16HwDevice::ConstructL() sl@0: { sl@0: CMMFGsm610ToPcm16Codec* ptr= new(ELeave)CMMFGsm610ToPcm16Codec(); sl@0: CleanupStack::PushL(ptr); sl@0: ptr->ConstructL(); sl@0: iCodec = ptr; sl@0: CleanupStack::Pop(ptr); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CMmfPcm16ToGsm610HwDevice sl@0: * sl@0: */ sl@0: CMmfPcm16ToGsm610HwDevice* CMmfPcm16ToGsm610HwDevice::NewL() sl@0: { sl@0: CMmfPcm16ToGsm610HwDevice* self=new(ELeave) CMmfPcm16ToGsm610HwDevice(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Codec sl@0: * @return CMMFSwCodec& sl@0: * sl@0: */ sl@0: CMMFSwCodec& CMmfPcm16ToGsm610HwDevice::Codec() sl@0: { sl@0: return *iCodec; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ~CMmfPcm16ToGsm610HwDevice sl@0: * sl@0: */ sl@0: CMmfPcm16ToGsm610HwDevice::~CMmfPcm16ToGsm610HwDevice() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConstructL sl@0: * sl@0: */ sl@0: void CMmfPcm16ToGsm610HwDevice::ConstructL() sl@0: { sl@0: CMMFPcm16ToGsm610Codec* ptr =new(ELeave) CMMFPcm16ToGsm610Codec(); sl@0: CleanupStack::PushL(ptr); sl@0: ptr->ConstructL(); sl@0: iCodec = ptr; sl@0: CleanupStack::Pop(ptr); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CMMFGsm610ToPcm16Codec sl@0: * sl@0: */ sl@0: CMMFGsm610ToPcm16Codec::CMMFGsm610ToPcm16Codec() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConstructL sl@0: * sl@0: */ sl@0: void CMMFGsm610ToPcm16Codec::ConstructL() sl@0: { sl@0: iGsmDecoder = new (ELeave) CGSM610FR_Decoder; sl@0: iGsmDecoder->ConstructL(); sl@0: iGsmDecoder->StartL(); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * NewL sl@0: * sl@0: */ sl@0: CMMFGsm610ToPcm16Codec* CMMFGsm610ToPcm16Codec::NewL() sl@0: { sl@0: CMMFGsm610ToPcm16Codec* self=new(ELeave) CMMFGsm610ToPcm16Codec(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ~CMMFGsm610ToPcm16Codec sl@0: * sl@0: */ sl@0: CMMFGsm610ToPcm16Codec::~CMMFGsm610ToPcm16Codec() sl@0: { sl@0: delete iGsmDecoder; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ProcessL sl@0: * @param aSource sl@0: * @param aDest sl@0: * @pre input buffer length is mod 65 sl@0: * @pre output buffer has sufficient space for coded input sl@0: * sl@0: */ sl@0: CMMFSwCodec::TCodecProcessResult CMMFGsm610ToPcm16Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDest) sl@0: { sl@0: CMMFSwCodec::TCodecProcessResult result; sl@0: result.iCodecProcessStatus = result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete; sl@0: sl@0: //convert from generic CMMFBuffer to CMMFDataBuffer sl@0: CMMFBuffer* pSrcBuffer =const_cast(&aSrc); sl@0: if( !pSrcBuffer ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: CMMFDataBuffer* src = static_cast( pSrcBuffer ); sl@0: if( !src ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: CMMFDataBuffer* dst = static_cast(&aDest); sl@0: if( !dst ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: if(!CheckInputBuffers( *src, *dst )) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: TInt numBuffersToProcess = NumBuffersToProcess( *src ); sl@0: TUint8* pSrc = CONST_CAST(TUint8*,src->Data().Ptr()); sl@0: TUint8* pDst = CONST_CAST(TUint8*,dst->Data().Ptr()); sl@0: sl@0: for( TInt count = 0; count < numBuffersToProcess; count++ ) sl@0: { sl@0: // Encode two frames of gsm data sl@0: iGsmDecoder->ExecuteL( pSrc, pDst ); sl@0: pSrc += KGsmFrameSize;; sl@0: pDst += KPcmDataForGsmFrame; sl@0: result.iSrcBytesProcessed += KGsmFrameSize; sl@0: result.iDstBytesAdded += KPcmDataForGsmFrame; sl@0: } sl@0: sl@0: dst->Data().SetLength( result.iDstBytesAdded ); sl@0: __ASSERT_DEBUG( ProcessPostCondition( result ), TMmfGsmCodecPanicsNameSpace::Panic( TMmfGsmCodecPanicsNameSpace::EPostConditionViolation )); sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CheckInputBuffers sl@0: * @param aSrc sl@0: * @param aDest sl@0: * @return TBool sl@0: * This function returns ETrue if the preconditions of processL are met sl@0: * sl@0: */ sl@0: TBool CMMFGsm610ToPcm16Codec::CheckInputBuffers( CMMFDataBuffer& aSrc, CMMFDataBuffer& aDest ) sl@0: { sl@0: TBool result = ETrue; sl@0: TInt numInputSubFrames = aSrc.Data().Length() / KGsmFrameSize; sl@0: TInt numOutputSubFrames = aDest.Data().MaxLength() / KPcmDataForGsmFrame; sl@0: TBool validInputDataLength = (aSrc.Data().Length() % KGsmFrameSize == 0); sl@0: sl@0: if( (numInputSubFrames > numOutputSubFrames) || // sufficient space in the output for the input sl@0: (aSrc.Position() > 0 ) || // position must be zero since we can eat all the data sl@0: (aDest.Position() > 0 ) || sl@0: (!validInputDataLength)) //position must be zero sl@0: { sl@0: result = EFalse; sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * NumBuffersToProcess sl@0: * @param aSrc sl@0: * @return TBool sl@0: * This method returns the number of buffers to process sl@0: * sl@0: */ sl@0: TInt CMMFGsm610ToPcm16Codec::NumBuffersToProcess( const CMMFDataBuffer& aSrc ) sl@0: { sl@0: TInt numBuffers = (aSrc.Data().Length() / KGsmFrameSize ); sl@0: return numBuffers; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ProcessPostCondition sl@0: * @param aResult sl@0: * @return TBool Etrue if the post condition is satisfied sl@0: * sl@0: **/ sl@0: TBool CMMFGsm610ToPcm16Codec::ProcessPostCondition( const CMMFSwCodec::TCodecProcessResult& aResult ) sl@0: { sl@0: TBool status = ETrue; sl@0: if( (aResult.iSrcBytesProcessed / KGsmFrameSize ) != (aResult.iDstBytesAdded / KPcmDataForGsmFrame ) ) sl@0: { sl@0: status = EFalse; sl@0: } sl@0: return status; sl@0: } sl@0: sl@0: /************************>----------------------------------<*****************************/ sl@0: sl@0: /** sl@0: * sl@0: * CMMFPcm16ToGsm610Codec sl@0: * sl@0: */ sl@0: CMMFPcm16ToGsm610Codec::CMMFPcm16ToGsm610Codec() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConstructL sl@0: * sl@0: */ sl@0: void CMMFPcm16ToGsm610Codec::ConstructL() sl@0: { sl@0: iGsmEncoder = new (ELeave) CGSM610FR_Encoder; sl@0: iGsmEncoder->ConstructL(); sl@0: iGsmEncoder->StartL(); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * NewL sl@0: * sl@0: */ sl@0: CMMFPcm16ToGsm610Codec* CMMFPcm16ToGsm610Codec::NewL() sl@0: { sl@0: CMMFPcm16ToGsm610Codec* self=new(ELeave) CMMFPcm16ToGsm610Codec(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CMMFPcm16ToGsm610Codec sl@0: * sl@0: */ sl@0: CMMFPcm16ToGsm610Codec::~CMMFPcm16ToGsm610Codec() sl@0: { sl@0: delete iGsmEncoder; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ProcessL sl@0: * @param aSource sl@0: * @param aDest TCodecProcessResult sl@0: * @return sl@0: * @pre input buffer length is mod 320 sl@0: * @pre output buffer has sufficient space for coded input sl@0: */ sl@0: CMMFSwCodec::TCodecProcessResult CMMFPcm16ToGsm610Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDest) sl@0: { sl@0: CMMFSwCodec::TCodecProcessResult result; sl@0: result.iCodecProcessStatus = result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete; sl@0: sl@0: //convert from generic CMMFBuffer to CMMFDataBuffer sl@0: CMMFBuffer* pSrcBuffer =const_cast(&aSrc); sl@0: if( !pSrcBuffer ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: CMMFDataBuffer* src = static_cast( pSrcBuffer ); sl@0: if( !src ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: CMMFDataBuffer* dst = static_cast(&aDest); sl@0: if( !dst ) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: sl@0: if(!CheckInputBuffers( *src, *dst )) sl@0: { sl@0: User::Leave( KErrArgument ); sl@0: } sl@0: sl@0: TInt numBuffersToProcess = NumBuffersToProcess( *src ); sl@0: TUint8* pSrc = CONST_CAST(TUint8*,src->Data().Ptr()); sl@0: TUint8* pDst = CONST_CAST(TUint8*,dst->Data().Ptr()); sl@0: sl@0: for( TInt count = 0; count < numBuffersToProcess; count++ ) sl@0: { sl@0: // Encode two frames of gsm data sl@0: iGsmEncoder->ExecuteL (pSrc, pDst); sl@0: pSrc += KPcmDataForGsmFrame; sl@0: pDst += KGsmFrameSize; sl@0: result.iSrcBytesProcessed += KPcmDataForGsmFrame; sl@0: result.iDstBytesAdded += KGsmFrameSize; sl@0: } sl@0: sl@0: dst->Data().SetLength( result.iDstBytesAdded ); sl@0: sl@0: __ASSERT_DEBUG( ProcessPostCondition(result), TMmfGsmCodecPanicsNameSpace::Panic( TMmfGsmCodecPanicsNameSpace::EPostConditionViolation )); sl@0: sl@0: return result ; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CheckInputBuffers sl@0: * @param aSrc sl@0: * @param aDest sl@0: * @return TBool sl@0: * This function returns ETrue if there is sufficient space sl@0: * in the output buffer for the coded input and sl@0: * the position of both input buffers is zero sl@0: * sl@0: */ sl@0: TBool CMMFPcm16ToGsm610Codec::CheckInputBuffers( CMMFDataBuffer& aSrc, CMMFDataBuffer& aDest ) sl@0: { sl@0: TBool result = ETrue; sl@0: TInt numInputSubFrames = aSrc.Data().Length() / KPcmDataForGsmFrame; sl@0: TInt numOutputSubFrames = aDest.Data().MaxLength() / KGsmFrameSize; sl@0: TBool validInputDataLength = (aSrc.Data().Length() % KPcmDataForGsmFrame == 0); sl@0: sl@0: if( (numInputSubFrames > numOutputSubFrames) || // sufficient space in the output for the input sl@0: (aSrc.Position() > 0 ) || // position must be zero since we can eat all the data sl@0: (aDest.Position() > 0 ) || sl@0: (!validInputDataLength)) //position must be zero sl@0: { sl@0: result = EFalse; sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * NumBuffersToProcess sl@0: * @param aSrc sl@0: * @return TBool sl@0: * This method returns the number of buffers to process sl@0: * sl@0: */ sl@0: TInt CMMFPcm16ToGsm610Codec::NumBuffersToProcess( const CMMFDataBuffer& aSrc ) sl@0: { sl@0: TInt numBuffers = ( aSrc.Data().Length() / KPcmDataForGsmFrame ); sl@0: return numBuffers; sl@0: } sl@0: