devsound/devsoundrefplugin/src/plugin/audio/Gsm610/GSM610.CPP
changeset 0 79dd3e2336a0
--- /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 <e32std.h>
+#include <mmf/server/mmfswcodecwrapper.h>
+
+#include <ecom/implementationproxy.h>
+#include "GSM610.H"
+#include <mmfcodec/gsm610/gsm610common.h>
+#include <ecom/ecom.h>
+#include <e32def.h>
+#include <mmf/plugin/mmfhwdeviceimplementationuids.hrh>
+
+/**
+*
+* 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<CMMFBuffer*>(&aSrc);
+	if( !pSrcBuffer )
+		{
+		User::Leave( KErrArgument );
+		}
+
+	CMMFDataBuffer* src = static_cast<CMMFDataBuffer*>( pSrcBuffer );
+    if( !src )
+		{
+		User::Leave( KErrArgument );
+		}
+
+	CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>(&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<CMMFBuffer*>(&aSrc);
+	if( !pSrcBuffer )
+		{
+		User::Leave( KErrArgument );
+		}
+
+	CMMFDataBuffer* src = static_cast<CMMFDataBuffer*>( pSrcBuffer );
+    if( !src )
+		{
+		User::Leave( KErrArgument );
+		}
+
+	CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>(&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;
+	}
+