sl@0: // Copyright (c) 2003-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: // sl@0: sl@0: // EPOC includes sl@0: #include sl@0: #include sl@0: #include "types.h" sl@0: #include "gsm610fr.h" sl@0: #include "MMFAudioCodecBase.h" sl@0: sl@0: // Test system includes sl@0: #include "TSU_MMF_SWCODECDEVICES.h" sl@0: #include "TSU_MMF_SwCodecDevices_BufferSizes.h" sl@0: #include "TSU_MMF_DeviceSuite.h" sl@0: #include "MMFAudioSPcm16ToALawCodec.h" sl@0: #include "MMFAudioALawToS16PcmCodec.h" sl@0: #include "MMFAudioMuLawToS16PcmCodec.h" sl@0: #include "MMFAudioSPcm16ToMuLawCodec.h" sl@0: #include "mmfpcm16ToImaAdpcm.h" sl@0: #include "MmfImaAdpcmtopcm16hwdevice.h" sl@0: #include "GSM610.H" sl@0: sl@0: /** sl@0: * sl@0: * CTestStep_MMF_SwCodecDevices sl@0: * sl@0: **/ sl@0: CTestStep_MMF_SwCodecDevices::CTestStep_MMF_SwCodecDevices() sl@0: { sl@0: iHeapSize = 300000; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ~CTestStep_MMF_SwCodecDevices sl@0: * sl@0: */ sl@0: CTestStep_MMF_SwCodecDevices::~CTestStep_MMF_SwCodecDevices() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * SetSuite sl@0: * @param aPtr ref to the test suite sl@0: * sl@0: **/ sl@0: void CTestStep_MMF_SwCodecDevices::SetSuite( CTestSuite_MMF_SwCodecDevices* aPtr ) sl@0: { sl@0: iRefSuite = aPtr; sl@0: } sl@0: /** sl@0: * sl@0: * GetSuite sl@0: * @return CTestSuite_MMF_SwCodecDevices* sl@0: * sl@0: **/ sl@0: CTestSuite_MMF_SwCodecDevices* CTestStep_MMF_SwCodecDevices::GetSuite() sl@0: { sl@0: return iRefSuite; sl@0: } sl@0: /** sl@0: * sl@0: * CTest_MMF_Gsm610 sl@0: * sl@0: */ sl@0: CTest_MMF_Gsm610::CTest_MMF_Gsm610() sl@0: { sl@0: sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CTest_MMF_SwCodecDevices_U_0001 sl@0: * sl@0: */ sl@0: CTest_MMF_SwCodecDevices_U_0001::CTest_MMF_SwCodecDevices_U_0001() sl@0: { sl@0: // store the name of this test case sl@0: // this is the name that is used by the script file sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0001-HP"); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CTest_MMF_SwCodecDevices_U_0001 sl@0: * sl@0: **/ sl@0: CTest_MMF_SwCodecDevices_U_0001::~CTest_MMF_SwCodecDevices_U_0001() sl@0: { sl@0: sl@0: } sl@0: /** sl@0: * sl@0: * sl@0: * ~CTest_MMF_Gsm610 sl@0: * sl@0: */ sl@0: CTest_MMF_Gsm610::~CTest_MMF_Gsm610() sl@0: { sl@0: // nothing to do .. sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: */ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0001::DoTestStepL() sl@0: { sl@0: __MM_HEAP_MARK; sl@0: TVerdict result = EPass ; sl@0: sl@0: CMmfGsm610ToPcm16HwDevice* pDecoder = CMmfGsm610ToPcm16HwDevice::NewL(); sl@0: CleanupStack::PushL(pDecoder); sl@0: sl@0: // do the same for the inverse operation sl@0: CMmfPcm16ToGsm610HwDevice* pEncoder = CMmfPcm16ToGsm610HwDevice::NewL(); sl@0: CleanupStack::PushL(pEncoder); sl@0: CMMFSwCodec& theEncode = pEncoder->Codec(); sl@0: sl@0: //[ create buffers of the appropriate size ] sl@0: const TInt srcBufferSize = theEncode.SourceBufferSize(); sl@0: const TInt sinkBufferSize = theEncode.SinkBufferSize(); sl@0: const TInt codedBufferSize = 76*4* KNumFramesInABuffer; // number of coded buffers * size of coded buffer 63*2 sl@0: iNumCodedFrames = KNumFramesInABuffer; //XXX claculate these constants soon sl@0: sl@0: iScratchData = CMMFDescriptorBuffer::NewL( codedBufferSize); sl@0: sl@0: //[ pcm data buffers ] sl@0: iRefSrcData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: iDecodedData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: sl@0: //[ coded data buffers ] sl@0: iRefCodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: iRefDecodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: iCodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: sl@0: //[ for now process only the first few buffers sl@0: // and encode the data] sl@0: INFO_PRINTF1(_L("Encoding Frame...")); sl@0: TInt srcFileSize = 0; sl@0: iSrcFile.Size( srcFileSize); sl@0: TInt buffLen =iRefSrcData->Data().MaxLength(); sl@0: TInt numBuffers = srcFileSize/buffLen; sl@0: if( numBuffers > 4 ) // [ not all buffers are processed without error sl@0: // and this is the intention probably of the test sequences] sl@0: numBuffers = 4; sl@0: TInt badBufferCount = 0; sl@0: TInt goodBufferCount = 0; sl@0: sl@0: for( TInt bufferCount = 0; bufferCount < numBuffers; bufferCount++ ) sl@0: { sl@0: //[precondition pointers are ok] sl@0: ReadDataBufferL(iSrcFile, *iRefSrcData ); sl@0: sl@0: ParseCodedDataL(iRefCodedData); sl@0: sl@0: CMMFSwCodec::TCodecProcessResult encodeRes = theEncode.ProcessL( *iRefSrcData, *iCodedData ); sl@0: if( encodeRes != CMMFSwCodec::TCodecProcessResult::EProcessComplete ) sl@0: { sl@0: INFO_PRINTF1( _L("Error Failed to complete coding") ); sl@0: return EFail; sl@0: } sl@0: sl@0: //[ compare results ] sl@0: if( !CompareEncodeResults( iCodedData, iRefCodedData ) ) sl@0: { sl@0: result = EFail; sl@0: badBufferCount++; sl@0: } sl@0: else sl@0: { sl@0: goodBufferCount++; sl@0: } sl@0: sl@0: } sl@0: sl@0: //[ log number of good buffers & number of bad buffers ] sl@0: INFO_PRINTF4(_L("Good Buffers %d, Bad Buffers %d, Total Buffers %d"), sl@0: goodBufferCount, badBufferCount, badBufferCount+goodBufferCount ); sl@0: sl@0: //[pop data from the cleanup stack ] sl@0: CleanupStack::PopAndDestroy(2, pDecoder); //pDecoder, theCodec sl@0: sl@0: delete iRefSrcData; // reference source data sl@0: iRefSrcData = NULL; sl@0: delete iRefCodedData; //reference coded data sl@0: iRefCodedData = NULL; sl@0: delete iRefDecodedData; // reference decoded data sl@0: iRefDecodedData = NULL; sl@0: delete iCodedData; // buffer of coded data sl@0: iCodedData = NULL; sl@0: delete iDecodedData; // buffer of actual decoded data sl@0: iDecodedData = NULL; sl@0: delete iScratchData; // scratch data buffer sl@0: iScratchData = NULL; sl@0: sl@0: __MM_HEAP_MARKEND; sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ParseCodedDataL sl@0: * sl@0: */ sl@0: void CTest_MMF_Gsm610::ParseCodedDataL( CMMFDataBuffer* aBuffer ) sl@0: { sl@0: codes frame0; sl@0: codes frame1; sl@0: sl@0: //[ read all the coded data into the scratch buffer from reference file ] sl@0: ReadDataBufferL( iCodedFile, *iScratchData ); sl@0: TUint8* dest = const_cast(aBuffer->Data().Ptr()); sl@0: TUint8* src = const_cast(iScratchData->Data().Ptr()); sl@0: sl@0: //[ for all the coded frames parse these frames to proper coded form ] sl@0: for( TInt count = 0; count < iNumCodedFrames; count++ ) sl@0: { sl@0: // parse data to frame sl@0: ParseFrameL( frame0, src ); sl@0: ParseFrameL( frame1, src ); sl@0: //[ finally pack the two frames into the coded data buffer ] sl@0: PackFrame0( &frame0, reinterpret_cast(dest) ); sl@0: PackFrame1( &frame1, reinterpret_cast(dest) ); sl@0: dest+= KGsmFrameSize; sl@0: } sl@0: sl@0: aBuffer->Data().SetLength(KGsmFrameSize*iNumCodedFrames); sl@0: } sl@0: /** sl@0: * sl@0: * ParseFrame sl@0: * @param aFrame this stores the gsm frame in an unpacked structure sl@0: * @param aBuffer this contains the reference file data as 76 words sl@0: * sl@0: */ sl@0: void CTest_MMF_Gsm610::ParseFrameL( struct codes& aFrame, TUint8* &aSrc ) sl@0: { sl@0: for(TInt i = 0; i < 8; i++ ) sl@0: { sl@0: aFrame.LARc[i] = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.LARc[i] |= static_cast(*aSrc++ << 8 ); sl@0: } sl@0: sl@0: for( TInt j = 0; j < 4; j++ ) sl@0: { sl@0: aFrame.sfc[j].Nc = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.sfc[j].Nc |= static_cast(*aSrc++ << 8 ); sl@0: aFrame.sfc[j].bc = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.sfc[j].bc |= static_cast(*aSrc++ << 8 ); sl@0: aFrame.sfc[j].Mc = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.sfc[j].Mc |= static_cast(*aSrc++ << 8 ); sl@0: aFrame.sfc[j].xmaxc = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.sfc[j].xmaxc |= static_cast(*aSrc++ << 8 ); sl@0: sl@0: for( TInt k = 0; k < 13; k++ ) sl@0: { sl@0: aFrame.sfc[j].xMc[k] = static_cast (*aSrc++ &KAndMask8bit ); sl@0: aFrame.sfc[j].xMc[k] |= static_cast(*aSrc++ << 8 ); sl@0: } sl@0: sl@0: } sl@0: sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: */ sl@0: enum TVerdict CTest_MMF_SwCodecDevices_U_0001::DoTestStepPreambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: //[ connect to the file server ] sl@0: User::LeaveIfError( iFs.Connect()); sl@0: sl@0: //[ read the ref source data ] sl@0: if(!GetStringFromConfig(_L("SectionOne"), _L("SourceData01"), iSourceDataFile) || sl@0: !GetStringFromConfig(_L("SectionOne"), _L("CodedData01"), iCodedDataFile) || sl@0: !GetStringFromConfig(_L("SectionOne"), _L("DecodedData01"), iDecodedDataFile) ) sl@0: { sl@0: return EInconclusive; sl@0: } sl@0: sl@0: //[ open the data files] sl@0: OpenFileL(iSrcFile,iSourceDataFile ); sl@0: OpenFileL(iCodedFile,iCodedDataFile ); sl@0: OpenFileL(iDecodeFile,iDecodedDataFile); sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareCodedResults sl@0: * @param aEncodedFrame sl@0: * @param aRefFrame sl@0: * @result TBool sl@0: * sl@0: */ sl@0: TBool CTest_MMF_Gsm610::CompareEncodeResults( CMMFDataBuffer* aEncoded, CMMFDataBuffer* aRefFrame ) sl@0: { sl@0: TBool result = ETrue; sl@0: sl@0: //[precondition no encoded frames == refframes ] sl@0: __ASSERT_DEBUG(aEncoded,Panic(EBadArgument)); sl@0: __ASSERT_DEBUG(aRefFrame,Panic(EBadArgument)); sl@0: sl@0: TInt upperLimit = aEncoded->Data().Length()/KGsmFrameSize; sl@0: sl@0: const CMMFDataBuffer* encoded = STATIC_CAST(const CMMFDataBuffer*, aEncoded); sl@0: const CMMFDataBuffer* reference = STATIC_CAST(CMMFDataBuffer*, aRefFrame); sl@0: sl@0: TUint8* pFrames = CONST_CAST(TUint8*,encoded->Data().Ptr()); sl@0: TUint8* pRefFrames = CONST_CAST(TUint8*,reference->Data().Ptr()); sl@0: sl@0: TInt badFrameCount = 0; sl@0: TInt goodFrameCount = 0; sl@0: sl@0: //[ for all frames ] sl@0: for( TInt index = 0; index < upperLimit; index++ ) sl@0: { sl@0: //[ compare src and ref frame] sl@0: if( !CompareGsm610Frames( pFrames, pRefFrames )) sl@0: { sl@0: result = EFalse; sl@0: badFrameCount++; sl@0: INFO_PRINTF2(_L("Bad Frame Number: %d"), index ); sl@0: } sl@0: else{ sl@0: goodFrameCount++; sl@0: } sl@0: sl@0: //[ increment frame pointers by size of gsmencoded frame sl@0: pFrames += KGsmFrameSize; sl@0: pRefFrames += KGsmFrameSize; sl@0: } sl@0: sl@0: //[ log number of good frames & number of bad frames ] sl@0: INFO_PRINTF4(_L("Good Frames %d, Bad Frames %d, Total Frames %d"), sl@0: goodFrameCount, badFrameCount, badFrameCount+goodFrameCount ); sl@0: sl@0: return result ; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareGsm610Frames sl@0: * This function compares two encoded gsm610 frames sl@0: * @result TBool Frames are the same or different sl@0: * sl@0: **/ sl@0: TBool CTest_MMF_Gsm610::CompareGsm610Frames( TUint8* aGsmFrame,TUint8* aRefGsmFrame ) sl@0: { sl@0: TBool result = ETrue; sl@0: ASSERT( aGsmFrame ); sl@0: __ASSERT_DEBUG(aGsmFrame,Panic(EBadArgument)); sl@0: __ASSERT_DEBUG(aRefGsmFrame,Panic(EBadArgument)); sl@0: sl@0: codes codeBuf0; sl@0: codes codeBuf1; sl@0: codes refCodeBuf0; sl@0: codes refCodeBuf1; sl@0: sl@0: UnpackFrame0(&codeBuf0, aGsmFrame ); sl@0: UnpackFrame1(&codeBuf1, aGsmFrame ); sl@0: UnpackFrame0(&refCodeBuf0, aRefGsmFrame ); sl@0: UnpackFrame1(&refCodeBuf1, aRefGsmFrame ); sl@0: sl@0: if( !Compare( codeBuf0, refCodeBuf0 ) || sl@0: !Compare( codeBuf1, refCodeBuf1) ) sl@0: sl@0: { sl@0: //LogGsmFrames( codeBuf0, refCodeBuf0 ); // add for debug reasons sl@0: //LogGsmFrames( codeBuf1, refCodeBuf1 ); // add for debugging reasons sl@0: result = EFalse; sl@0: } sl@0: sl@0: return result ; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * LogGsmFrames sl@0: * @param aGsmFrame sl@0: * @param aRefGsmFrame sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::LogGsmFrames( codes& aGsmFrame, codes& aRefGsmFrame ) sl@0: { sl@0: //[ print the quantized lar coefficients ] sl@0: INFO_PRINTF1(_L("Coded Frame:")); sl@0: LogGsmFrame( aGsmFrame ); sl@0: INFO_PRINTF1(_L("Reference Frame:")); sl@0: LogGsmFrame( aRefGsmFrame ); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * LogGsmFrame sl@0: * prints a GsmFrame to the test log sl@0: * @param aFrame sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::LogGsmFrame ( codes& aFrame ) sl@0: { sl@0: INFO_PRINTF2(_L("LARc[0] = %d"), aFrame.LARc[0]); sl@0: INFO_PRINTF2(_L("LARc[1] = %d"), aFrame.LARc[1]); sl@0: INFO_PRINTF2(_L("LARc[2] = %d"), aFrame.LARc[2]); sl@0: INFO_PRINTF2(_L("LARc[3] = %d"), aFrame.LARc[3]); sl@0: INFO_PRINTF2(_L("LARc[4] = %d"), aFrame.LARc[4]); sl@0: INFO_PRINTF2(_L("LARc[5] = %d"), aFrame.LARc[5]); sl@0: INFO_PRINTF2(_L("LARc[6] = %d"), aFrame.LARc[6]); sl@0: INFO_PRINTF2(_L("LARc[7] = %d"), aFrame.LARc[7]); sl@0: sl@0: //[ for each sub frame print its data ] sl@0: for( TInt i = 0; i < 4; i++ ) sl@0: { sl@0: INFO_PRINTF2(_L("Nc = %d"), aFrame.sfc[i].Nc); sl@0: INFO_PRINTF2(_L("bc = %d"), aFrame.sfc[i].bc); sl@0: INFO_PRINTF2(_L("Mc= %d"), aFrame.sfc[i].Mc); sl@0: INFO_PRINTF2(_L("xmaxc = %d"), aFrame.sfc[i].xmaxc); sl@0: INFO_PRINTF2(_L("xMc[0] = %d"), aFrame.sfc[i].xMc[0]); sl@0: INFO_PRINTF2(_L("xMc[1] = %d"), aFrame.sfc[i].xMc[1]); sl@0: INFO_PRINTF2(_L("xMc[2] = %d"), aFrame.sfc[i].xMc[2]); sl@0: INFO_PRINTF2(_L("xMc[3] = %d"), aFrame.sfc[i].xMc[3]); sl@0: INFO_PRINTF2(_L("xMc[4] = %d"), aFrame.sfc[i].xMc[4]); sl@0: INFO_PRINTF2(_L("xMc[5] = %d"), aFrame.sfc[i].xMc[5]); sl@0: INFO_PRINTF2(_L("xMc[6] = %d"), aFrame.sfc[i].xMc[6]); sl@0: INFO_PRINTF2(_L("xMc[7] = %d"), aFrame.sfc[i].xMc[7]); sl@0: INFO_PRINTF2(_L("xMc[8] = %d"), aFrame.sfc[i].xMc[8]); sl@0: INFO_PRINTF2(_L("xMc[9] = %d"), aFrame.sfc[i].xMc[9]); sl@0: INFO_PRINTF2(_L("xMc[10] = %d"), aFrame.sfc[i].xMc[10]); sl@0: INFO_PRINTF2(_L("xMc[11] = %d"), aFrame.sfc[i].xMc[11]); sl@0: INFO_PRINTF2(_L("xMc[12] = %d"), aFrame.sfc[i].xMc[12]); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Compare sl@0: * sl@0: **/ sl@0: TBool CTest_MMF_Gsm610::Compare( codes& aFrame1, codes& aFrame2 ) sl@0: { sl@0: TBool result = ETrue; sl@0: sl@0: if( (aFrame1.LARc[0] != aFrame2.LARc[0] ) || sl@0: (aFrame1.LARc[1] != aFrame2.LARc[1] ) || sl@0: (aFrame1.LARc[2] != aFrame2.LARc[2] ) || sl@0: (aFrame1.LARc[3] != aFrame2.LARc[3] ) || sl@0: (aFrame1.LARc[4] != aFrame2.LARc[4] ) || sl@0: (aFrame1.LARc[5] != aFrame2.LARc[5] ) || sl@0: (aFrame1.LARc[6] != aFrame2.LARc[6] ) || sl@0: (aFrame1.LARc[7] != aFrame2.LARc[7] ) ) sl@0: { sl@0: result = EFalse; sl@0: } sl@0: sl@0: for( TInt i = 0; i < 4; i++ ) sl@0: { sl@0: if( sl@0: (aFrame1.sfc[i].Nc != aFrame2.sfc[i].Nc) || sl@0: (aFrame1.sfc[i].bc != aFrame2.sfc[i].bc) || sl@0: (aFrame1.sfc[i].Mc != aFrame2.sfc[i].Mc) || sl@0: (aFrame1.sfc[i].xmaxc != aFrame2.sfc[i].xmaxc) || sl@0: (aFrame1.sfc[i].xMc[0] != aFrame2.sfc[i].xMc[0]) || sl@0: (aFrame1.sfc[i].xMc[1] != aFrame2.sfc[i].xMc[1]) || sl@0: (aFrame1.sfc[i].xMc[2] != aFrame2.sfc[i].xMc[2]) || sl@0: (aFrame1.sfc[i].xMc[3] != aFrame2.sfc[i].xMc[3]) || sl@0: (aFrame1.sfc[i].xMc[4] != aFrame2.sfc[i].xMc[4]) || sl@0: (aFrame1.sfc[i].xMc[5] != aFrame2.sfc[i].xMc[5]) || sl@0: (aFrame1.sfc[i].xMc[6] != aFrame2.sfc[i].xMc[6]) || sl@0: (aFrame1.sfc[i].xMc[7] != aFrame2.sfc[i].xMc[7]) || sl@0: (aFrame1.sfc[i].xMc[8] != aFrame2.sfc[i].xMc[8]) || sl@0: (aFrame1.sfc[i].xMc[9] != aFrame2.sfc[i].xMc[9]) || sl@0: (aFrame1.sfc[i].xMc[10] != aFrame2.sfc[i].xMc[10]) || sl@0: (aFrame1.sfc[i].xMc[11] != aFrame2.sfc[i].xMc[11]) || sl@0: (aFrame1.sfc[i].xMc[12] != aFrame2.sfc[i].xMc[12])) sl@0: { sl@0: result = EFail; sl@0: } sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareCodedResults sl@0: * sl@0: */ sl@0: TBool CTest_MMF_Gsm610::CompareDecodeResults(CMMFDataBuffer* aEncoded, CMMFDataBuffer* aRefFrame ) sl@0: { sl@0: TBool result = ETrue; sl@0: sl@0: //[ precondition the buffers are of the same length ] sl@0: __ASSERT_DEBUG(aEncoded,Panic(EBadArgument)); sl@0: __ASSERT_DEBUG(aRefFrame,Panic(EBadArgument)); sl@0: __ASSERT_DEBUG(aEncoded->Data().MaxLength() == aRefFrame->Data().MaxLength(),Panic(EBadArgument)); sl@0: sl@0: TUint8 *pResults = CONST_CAST(TUint8*,aEncoded->Data().Ptr()); sl@0: TUint8 *pRefData = CONST_CAST(TUint8*,aRefFrame->Data().Ptr()); sl@0: TInt numResults = aEncoded->Data().MaxLength(); sl@0: sl@0: if (Mem::Compare( pResults,numResults,pRefData,numResults)!=0) sl@0: { sl@0: result = EFalse; sl@0: } sl@0: sl@0: return result ; sl@0: } sl@0: /** sl@0: * sl@0: * ReadDataL sl@0: * Reads entire data file into buffer sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::ReadDataL( CMMFDataBuffer*& aBuffer, const TDesC& aFile1 ) sl@0: { sl@0: TFileName fileName = GetSuite()->DefaultPath(); sl@0: fileName.Append(aFile1); sl@0: sl@0: RFile file1; sl@0: User::LeaveIfError(file1.Open(iFs, fileName, EFileShareAny | EFileStream | EFileRead)); sl@0: CleanupClosePushL(file1); sl@0: TInt fileSize = 0; sl@0: User::LeaveIfError(file1.Size(fileSize)); sl@0: aBuffer = CMMFDescriptorBuffer::NewL(fileSize); sl@0: User::LeaveIfError(file1.Read( aBuffer->Data(),fileSize)); sl@0: CleanupStack::PopAndDestroy(1); //file1 sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * OpenFileL sl@0: * @param aFile sl@0: * @param aFileName sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::OpenFileL( RFile& aFile, const TDesC& aFileName ) sl@0: { sl@0: User::LeaveIfError(aFile.Open(iFs, aFileName, EFileShareAny | EFileStream | EFileRead)); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CloseFileL sl@0: * @param aFile sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::CloseFileL( RFile& aFile ) sl@0: { sl@0: aFile.Close(); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ReadDataBuffer sl@0: * @param aFile sl@0: * assumes file reads sufficient data sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::ReadDataBufferL( const RFile& aFile, CMMFDataBuffer& aBuffer ) sl@0: { sl@0: //[ The read will set the length of the descriptor to the number of bytes read] sl@0: User::LeaveIfError(aFile.Read( aBuffer.Data(),aBuffer.Data().MaxLength() )); sl@0: INFO_PRINTF2(_L("Bytes read = %d"), aBuffer.Data().Length() ); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * FillPcmBuffer sl@0: * @param aSrcBuffer sl@0: * Fill a buffer with a sine wave sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::FillPcmBuffer( CMMFDataBuffer& aSrcBuffer ) sl@0: { sl@0: //fill the Src Buffer sl@0: TUint8* pDst = CONST_CAST(TUint8*,aSrcBuffer.Data().Ptr()); sl@0: TInt length = aSrcBuffer.Data().MaxLength(); sl@0: sl@0: //[encode the data] sl@0: TInt16 srcValue = 0; sl@0: TReal val = 0.0; sl@0: TReal theta = 0.0; sl@0: for(TInt i=0; i( 1000 * val ); sl@0: *pDst++ = static_cast( srcValue & KAndMask8bit); sl@0: *pDst++ = static_cast((srcValue >> 8) & KAndMask8bit ); sl@0: //INFO_PRINTF2(_L("Sine = %d"), srcValue ); //uncomment for debugging purposes sl@0: } sl@0: sl@0: aSrcBuffer.Data().SetLength(length); sl@0: sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * @result TVerdict sl@0: * sl@0: */ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0001::DoTestStepPostambleL(void) sl@0: { sl@0: // close files sl@0: CloseFileL( iSrcFile ); sl@0: CloseFileL( iCodedFile ); sl@0: CloseFileL( iDecodeFile ); sl@0: //[ clean up the buffers etc ] sl@0: delete iRefSrcData; // reference source data sl@0: delete iRefCodedData; //reference coded data sl@0: delete iRefDecodedData; // reference decoded data sl@0: delete iCodedData; // buffer of coded data sl@0: delete iDecodedData; // buffer of actual decoded data sl@0: delete iScratchData; // scratch data buffer sl@0: return EPass; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * UnpackFrame0 sl@0: * @param aCodeBuf sl@0: * @param pbuf sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::UnpackFrame0(codes* aCodeBuf, TUint8* pbuf) sl@0: { sl@0: TInt16* LAR = aCodeBuf->LARc; sl@0: sl@0: // unpack the LAR[0..7] from the first 4.5 bytes sl@0: LAR[0] = (TInt16)((pbuf[0] & 0x3F)); sl@0: LAR[1] = (TInt16)(((pbuf[0] & 0xC0) >> 6) | ((pbuf[1] & 0x0F) << 2)); sl@0: LAR[2] = (TInt16)(((pbuf[1] & 0xF0) >> 4) | ((pbuf[2] & 0x01) << 4)); sl@0: LAR[3] = (TInt16)(((pbuf[2] & 0x3E) >> 1)); sl@0: LAR[4] = (TInt16)(((pbuf[2] & 0xC0) >> 6) | ((pbuf[3] & 0x03) << 2)); sl@0: LAR[5] = (TInt16)(((pbuf[3] & 0x3C) >> 2)); sl@0: LAR[6] = (TInt16)(((pbuf[3] & 0xC0) >> 6) | ((pbuf[4] & 0x01) << 2)); sl@0: LAR[7] = (TInt16)(((pbuf[4] & 0x0E) >> 1)); sl@0: sl@0: // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames sl@0: for(TInt i = 0; i < 4; i++) sl@0: { sl@0: struct sfcodes& c = aCodeBuf->sfc[i]; sl@0: #define sfb(x) (pbuf[4+i*7+x]) sl@0: c.Nc = (TInt16)(((sfb(0) & 0xF0) >> 4) | ((sfb(1) & 0x07) << 4)); sl@0: c.bc = (TInt16)(((sfb(1) & 0x18) >> 3)); sl@0: c.Mc = (TInt16)(((sfb(1) & 0x60) >> 5)); sl@0: c.xmaxc = (TInt16)(((sfb(1) & 0x80) >> 7) | ((sfb(2) & 0x1F) << 1)); sl@0: c.xMc[0] = (TInt16)(((sfb(2) & 0xE0) >> 5)); sl@0: c.xMc[1] = (TInt16)((sfb(3) & 0x07)); sl@0: c.xMc[2] = (TInt16)(((sfb(3) & 0x3C) >> 3)); sl@0: c.xMc[3] = (TInt16)(((sfb(3) & 0xC0) >> 6) | ((sfb(4) & 0x01) << 2)); sl@0: c.xMc[4] = (TInt16)(((sfb(4) & 0x0E) >> 1)); sl@0: c.xMc[5] = (TInt16)(((sfb(4) & 0x70) >> 4)); sl@0: c.xMc[6] = (TInt16)(((sfb(4) & 0x80) >> 7) | ((sfb(5) & 0x03) << 1)); sl@0: c.xMc[7] = (TInt16)(((sfb(5) & 0x1C) >> 2)); sl@0: c.xMc[8] = (TInt16)(((sfb(5) & 0xE0) >> 5)); sl@0: c.xMc[9] = (TInt16)((sfb(6) & 0x07)); sl@0: c.xMc[10] = (TInt16)(((sfb(6) & 0x38) >> 3)); sl@0: c.xMc[11] = (TInt16)(((sfb(6) & 0xC0) >> 6) | ((sfb(7) & 0x01) << 2)); sl@0: c.xMc[12] = (TInt16)(((sfb(7) & 0x0E) >> 1)); sl@0: #undef sfb sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * UnpackFrame1 sl@0: * @param aCodeBuf sl@0: * @param pbuf sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::UnpackFrame1(struct codes* aCodeBuf, TUint8* pbuf) sl@0: { sl@0: TInt16* LAR = aCodeBuf->LARc; sl@0: sl@0: // unpack the LAR[0..7] from the first 4.5 bytes sl@0: LAR[0] = (TInt16)(((pbuf[32] & 0xF0) >> 4) | ((pbuf[33] & 0x03) << 4)); sl@0: LAR[1] = (TInt16)(((pbuf[33] & 0xFC) >> 2)); sl@0: LAR[2] = (TInt16)(((pbuf[34] & 0x1F))); sl@0: LAR[3] = (TInt16)(((pbuf[34] & 0xE0) >> 5) | ((pbuf[35] & 0x03) << 3)); sl@0: LAR[4] = (TInt16)(((pbuf[35] & 0x3C) >> 2)); sl@0: LAR[5] = (TInt16)(((pbuf[35] & 0xC0) >> 6) | ((pbuf[36] & 0x03) << 2)); sl@0: LAR[6] = (TInt16)(((pbuf[36] & 0x1C) >> 2)); sl@0: LAR[7] = (TInt16)(((pbuf[36] & 0xE0) >> 5)); sl@0: sl@0: // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames sl@0: for(TInt i = 0; i < 4; i++) sl@0: { sl@0: struct sfcodes& c = aCodeBuf->sfc[i]; sl@0: #define sfb(x) (pbuf[37+i*7+x]) sl@0: c.Nc = (TInt16)(sfb(0) & 0x7F); sl@0: c.bc = (TInt16)(((sfb(0) & 0x80) >> 7) | ((sfb(1) & 0x01) << 1)); sl@0: c.Mc = (TInt16)(((sfb(1) & 0x06) >> 1)); sl@0: c.xmaxc = (TInt16)(((sfb(1) & 0xF8) >> 3) | ((sfb(2) & 0x01) << 5)); sl@0: c.xMc[0] = (TInt16)(((sfb(2) & 0x0E) >> 1)); sl@0: c.xMc[1] = (TInt16)(((sfb(2) & 0x70) >> 4)); sl@0: c.xMc[2] = (TInt16)(((sfb(2) & 0x80) >> 7) | ((sfb(3) & 0x03) << 1)); sl@0: c.xMc[3] = (TInt16)(((sfb(3) & 0x1C) >> 2)); sl@0: c.xMc[4] = (TInt16)(((sfb(3) & 0xE0) >> 5)); sl@0: c.xMc[5] = (TInt16)(((sfb(4) & 0x07))); sl@0: c.xMc[6] = (TInt16)(((sfb(4) & 0x38) >> 3)); sl@0: c.xMc[7] = (TInt16)(((sfb(4) & 0xC0) >> 6) | ((sfb(5) & 0x01) << 2)); sl@0: c.xMc[8] = (TInt16)(((sfb(5) & 0x0E) >> 1)); sl@0: c.xMc[9] = (TInt16)(((sfb(5) & 0x70) >> 4)); sl@0: c.xMc[10] = (TInt16)(((sfb(5) & 0x80) >> 7) | ((sfb(6) & 0x03) << 1)); sl@0: c.xMc[11] = (TInt16)(((sfb(6) & 0x1C) >> 2)); sl@0: c.xMc[12] = (TInt16)(((sfb(6) & 0xE0) >> 5)); sl@0: sl@0: #undef sfb sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * PackFrame0 sl@0: * Pack the codewords of the even frame into pack buffer. sl@0: * Packing as in MS gsm610 encoder. sl@0: * @param aCodeBuf Code words for one speech frame. sl@0: * @param pbuf the output buffer sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::PackFrame0(struct codes* aCodeBuf, TInt8* pbuf) sl@0: { sl@0: TInt16* LAR = aCodeBuf->LARc; sl@0: sl@0: // pack the LARc[0..7] into the first 4.5 bytes sl@0: *pbuf++ = (TUint8)(((LAR[0] ) & 0x3F) | ((LAR[1] << 6) & 0xC0)); sl@0: *pbuf++ = (TUint8)(((LAR[1] >> 2) & 0x0F) | ((LAR[2] << 4) & 0xF0)); sl@0: *pbuf++ = (TUint8)(((LAR[2] >> 4) & 0x01) | ((LAR[3] << 1) & 0x3E) | ((LAR[4] << 6) & 0xC0)); sl@0: *pbuf++ = (TUint8)(((LAR[4] >> 2) & 0x03) | ((LAR[5] << 2) & 0x3C) | ((LAR[6] << 6) & 0xC0)); sl@0: *pbuf = (TUint8)(((LAR[6] >> 2) & 0x01) | ((LAR[7] << 1) & 0x0E)); sl@0: sl@0: // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames sl@0: for(TInt i = 0; i < 4; i++) sl@0: { sl@0: struct sfcodes& c = aCodeBuf->sfc[i]; sl@0: *pbuf++ |= ((c.Nc << 4) & 0xF0); sl@0: *pbuf++ = (TUint8)(((c.Nc >> 4) & 0x07) | ((c.bc << 3) & 0x18) | ((c.Mc << 5) & 0x60) | ((c.xmaxc << 7) & 0x80)); sl@0: *pbuf++ = (TUint8)(((c.xmaxc >> 1) & 0x1F) | ((c.xMc[0] << 5) & 0xE0)); sl@0: *pbuf++ = (TUint8)((c.xMc[1] & 0x07) | ((c.xMc[2] << 3) & 0x38) | ((c.xMc[3] << 6) & 0xC0)); sl@0: *pbuf++ = (TUint8)(((c.xMc[3] >> 2) & 0x01) | ((c.xMc[4] << 1) & 0x0E) | ((c.xMc[5] << 4) & 0x70) | ((c.xMc[6] << 7) & 0x80)); sl@0: *pbuf++ = (TUint8)(((c.xMc[6] >> 1) & 0x03) | ((c.xMc[7] << 2) & 0x1C) | ((c.xMc[8] << 5) & 0xE0)); sl@0: *pbuf++ = (TUint8)((c.xMc[9] & 0x07) | ((c.xMc[10] << 3) & 0x38) | ((c.xMc[11] << 6) & 0xC0)); sl@0: *pbuf = (TUint8)(((c.xMc[11] >> 2) & 0x01) | ((c.xMc[12] << 1) & 0x0E)); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * PackFrame1 sl@0: * Pack the codewords of the even frame into pack buffer. sl@0: * Packing as in MS gsm610 encoder. sl@0: * @param aCodeBuf Code words for one speech frame. sl@0: * @param pbuf the output buffer sl@0: * sl@0: **/ sl@0: void CTest_MMF_Gsm610::PackFrame1(struct codes* aCodeBuf, TInt8* pbuf) sl@0: { sl@0: TInt16* LAR = aCodeBuf->LARc; sl@0: sl@0: pbuf += (PACKSIZE / 2); sl@0: sl@0: // pack the LARc[0..7] into the first 4.5 bytes, starting with the msb of the first byte sl@0: *pbuf++ = (TUint8) (pbuf[0] | ((LAR[0] << 4) & 0xF0)); sl@0: *pbuf++ = (TUint8)(((LAR[0] >> 4) & 0x03) | ((LAR[1] << 2) & 0xFC)); sl@0: *pbuf++ = (TUint8)(((LAR[2] ) & 0x1F) | ((LAR[3] << 5) & 0xE0)); sl@0: *pbuf++ = (TUint8)(((LAR[3] >> 3) & 0x03) | ((LAR[4] << 2) & 0x3C) | ((LAR[5] << 6) & 0xC0)); sl@0: *pbuf++ = (TUint8)(((LAR[5] >> 2) & 0x03) | ((LAR[6] << 2) & 0x1C) | ((LAR[7] << 5) & 0xE0)); sl@0: sl@0: // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames sl@0: for(TInt i = 0; i < 4; i++) sl@0: { sl@0: struct sfcodes& c = aCodeBuf->sfc[i]; sl@0: *pbuf++ = (TUint8)((c.Nc & 0x7F) | ((c.bc << 7) & 0x80)); sl@0: *pbuf++ = (TUint8)(((c.bc >> 1) & 0x01) | ((c.Mc << 1) & 0x06) | ((c.xmaxc << 3) & 0xF8)); sl@0: *pbuf++ = (TUint8)(((c.xmaxc >> 5) & 0x01) | ((c.xMc[0] << 1) & 0x0E) | ((c.xMc[1] << 4) & 0x70) | ((c.xMc[2] << 7) & 0x80)); sl@0: *pbuf++ = (TUint8)(((c.xMc[2] >> 1) & 0x03) | ((c.xMc[3] << 2) & 0x1C) | ((c.xMc[4] << 5) & 0xE0)); sl@0: *pbuf++ = (TUint8)(((c.xMc[5]) & 0x07) | ((c.xMc[6] << 3) & 0x38) | ((c.xMc[7] << 6) & 0xC0)); sl@0: *pbuf++ = (TUint8)(((c.xMc[7] >> 2) & 0x01) | ((c.xMc[8] << 1) & 0x0E) | ((c.xMc[9] << 4) & 0x70) | ((c.xMc[10] << 7) & 0x80)); sl@0: *pbuf++ = (TUint8)(((c.xMc[10] >> 1) & 0x03) | ((c.xMc[11] << 2) & 0x1C) | ((c.xMc[12] << 5) & 0xE0)); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CTest_MMF_SwCodecDevices_U_0001 sl@0: * sl@0: */ sl@0: CTest_MMF_SwCodecDevices_U_0002::CTest_MMF_SwCodecDevices_U_0002() sl@0: { sl@0: // store the name of this test case sl@0: // this is the name that is used by the script file sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0002-HP"); sl@0: } sl@0: /** sl@0: * sl@0: * CTest_MMF_SwCodecDevices_U_0001 sl@0: * sl@0: **/ sl@0: CTest_MMF_SwCodecDevices_U_0002::~CTest_MMF_SwCodecDevices_U_0002() sl@0: { sl@0: sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: **/ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0002::DoTestStepL() sl@0: { sl@0: __MM_HEAP_MARK; sl@0: TVerdict result = EPass ; sl@0: sl@0: CMmfGsm610ToPcm16HwDevice* pDecoder = CMmfGsm610ToPcm16HwDevice::NewL(); sl@0: CleanupStack::PushL(pDecoder); sl@0: //[ note this reference should be a ptr ] sl@0: CMMFSwCodec& theCodec = pDecoder->Codec(); sl@0: sl@0: //[ create buffers of the appropriate size ] sl@0: const TInt srcBufferSize = theCodec.SourceBufferSize(); sl@0: const TInt sinkBufferSize = theCodec.SinkBufferSize(); sl@0: const TInt codedBufferSize = 76*4* KNumFramesInABuffer; // number of coded buffers * size of coded buffer 63*2 sl@0: iNumCodedFrames = KNumFramesInABuffer; //XXX claculate these constants soon sl@0: sl@0: iScratchData = CMMFDescriptorBuffer::NewL( codedBufferSize); sl@0: sl@0: iRefCodedData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: iCodedData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: iRefDecodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: iDecodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize); sl@0: sl@0: //[ for now process only the first buffer ] sl@0: //[encode the data] sl@0: INFO_PRINTF1(_L("Decoding Frames...")); sl@0: TInt codedFileSize = 0; sl@0: iCodedFile.Size( codedFileSize); sl@0: sl@0: TInt numBuffers = codedFileSize/srcBufferSize; sl@0: if(numBuffers > 4 ) sl@0: numBuffers = 4; sl@0: TInt badBufferCount = 0; sl@0: TInt goodBufferCount = 0; sl@0: for( TInt bufferCount = 0; bufferCount < numBuffers; bufferCount++ ) sl@0: { sl@0: ReadDataBufferL(iDecodeFile, *iRefDecodedData ); sl@0: ParseCodedDataL(iCodedData); sl@0: sl@0: CMMFSwCodec::TCodecProcessResult decodeRes = theCodec.ProcessL( *iCodedData, *iDecodedData ); sl@0: if( decodeRes != CMMFSwCodec::TCodecProcessResult::EProcessComplete ) sl@0: { sl@0: INFO_PRINTF1( _L("Error Failed to complete decoding") ); sl@0: return EFail; sl@0: } sl@0: sl@0: //[ compare results ] sl@0: if(!CompareDecodeResults( iDecodedData, iRefDecodedData )) sl@0: { sl@0: result = EFail; sl@0: badBufferCount++; sl@0: } sl@0: else sl@0: { sl@0: goodBufferCount++; sl@0: } sl@0: sl@0: } sl@0: sl@0: //[ log number of good frames & number of bad frames ] sl@0: INFO_PRINTF4(_L("Good Frames %d, Bad Frames %d, Total Frames %d"), sl@0: goodBufferCount, badBufferCount, badBufferCount+goodBufferCount ); sl@0: sl@0: //[pop data from the cleanup stack ] sl@0: CleanupStack::PopAndDestroy(pDecoder); sl@0: sl@0: delete iRefCodedData; sl@0: iRefCodedData = NULL; sl@0: delete iRefDecodedData; sl@0: iRefDecodedData = NULL; sl@0: delete iDecodedData; sl@0: iDecodedData = NULL; sl@0: delete iCodedData ; sl@0: iCodedData = NULL; sl@0: delete iScratchData; sl@0: iScratchData = NULL; sl@0: sl@0: __MM_HEAP_MARKEND; sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: */ sl@0: enum TVerdict CTest_MMF_SwCodecDevices_U_0002::DoTestStepPreambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: //[ connect to the file server ] sl@0: User::LeaveIfError( iFs.Connect()); sl@0: sl@0: //[ read the ref source data ] sl@0: if(!GetStringFromConfig(_L("SectionOne"), _L("SourceData01"), iSourceDataFile) || sl@0: !GetStringFromConfig(_L("SectionOne"), _L("CodedData01"), iCodedDataFile) || sl@0: !GetStringFromConfig(_L("SectionOne"), _L("DecodedData01"), iDecodedDataFile) ) sl@0: { sl@0: return EInconclusive; sl@0: } sl@0: sl@0: //[ open the data files] sl@0: OpenFileL(iSrcFile,iSourceDataFile ); sl@0: OpenFileL(iCodedFile,iCodedDataFile ); sl@0: OpenFileL(iDecodeFile,iDecodedDataFile); sl@0: sl@0: iScratchData = CMMFDescriptorBuffer::NewL(KCodedBufferSize); sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * @result TVerdict sl@0: * sl@0: */ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0002::DoTestStepPostambleL(void) sl@0: { sl@0: // close files sl@0: CloseFileL( iCodedFile ); sl@0: CloseFileL( iDecodeFile ); sl@0: //[ clean up the buffers etc ] sl@0: delete iRefSrcData; // reference source data sl@0: delete iRefCodedData; //reference coded data sl@0: delete iRefDecodedData; // refernce decoded data sl@0: delete iCodedData; // buffer of coded data sl@0: delete iDecodedData; // buffer of actual decoded data sl@0: delete iScratchData; // scratch data buffer sl@0: return EPass; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CTest_MMF_SwCodecDevices_U_0003 sl@0: * sl@0: **/ sl@0: CTest_MMF_SwCodecDevices_U_0003::CTest_MMF_SwCodecDevices_U_0003() sl@0: { sl@0: // store the name of this test case sl@0: // this is the name that is used by the script file sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0003-HP"); sl@0: } sl@0: /** sl@0: * sl@0: * ~CTest_MMF_SwCodecDevices_U_0003 sl@0: * sl@0: **/ sl@0: CTest_MMF_SwCodecDevices_U_0003::~CTest_MMF_SwCodecDevices_U_0003() sl@0: { sl@0: sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: **/ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0003::DoTestStepL() sl@0: { sl@0: __MM_HEAP_MARK; sl@0: TVerdict result = EPass ; sl@0: sl@0: CMmfGsm610ToPcm16HwDevice* pDecoder = CMmfGsm610ToPcm16HwDevice::NewL(); sl@0: CleanupStack::PushL(pDecoder); sl@0: //[ note this reference should be a ptr ] sl@0: CMMFSwCodec& theCodec = pDecoder->Codec(); sl@0: sl@0: // do the same for the inverse operation sl@0: CMmfPcm16ToGsm610HwDevice* pEncoder = CMmfPcm16ToGsm610HwDevice::NewL(); sl@0: CleanupStack::PushL(pEncoder); sl@0: CMMFSwCodec& theEncode = pEncoder->Codec(); sl@0: sl@0: //[ create buffers of the appropriate size ] sl@0: const TInt srcBufferSize = theEncode.SourceBufferSize(); sl@0: const TInt sinkBufferSize = theEncode.SinkBufferSize(); sl@0: sl@0: iRefSrcData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: iRefCodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: iRefDecodedData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: iCodedData = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: iDecodedData = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: sl@0: //[ now get a sine wave of 800hz, code and decode and sl@0: // compare the results ] sl@0: FillPcmBuffer( *iRefSrcData ); sl@0: sl@0: // encode sl@0: CMMFSwCodec::TCodecProcessResult encodeRes = theEncode.ProcessL( *iRefSrcData, *iCodedData ); sl@0: if( encodeRes != CMMFSwCodec::TCodecProcessResult::EProcessComplete ) sl@0: { sl@0: INFO_PRINTF1( _L("Error Failed to complete coding") ); sl@0: return EFail; sl@0: } sl@0: sl@0: //decode sl@0: CMMFSwCodec::TCodecProcessResult decodeRes = theCodec.ProcessL( *iCodedData, *iDecodedData ); sl@0: if( decodeRes != CMMFSwCodec::TCodecProcessResult::EProcessComplete ) sl@0: { sl@0: INFO_PRINTF1( _L("Error Failed to complete decoding") ); sl@0: return EFail; sl@0: } sl@0: sl@0: //[ because the codec overwrites its input regenerate it ] sl@0: FillPcmBuffer( *iRefSrcData ); sl@0: sl@0: //[ NOW COMPARE THE RESULTS DISTORTION < 18 DB ] sl@0: sl@0: TUint8 *pResults = (TUint8*)(iDecodedData->Data().Ptr()); sl@0: TUint8 *pRefData = (TUint8*)(iRefSrcData->Data().Ptr()); sl@0: TInt numResults = iDecodedData->Data().MaxLength(); sl@0: TReal sum1 = 0.0; sl@0: TReal sum2 = 0.0; sl@0: TReal ratio = 0.0; sl@0: TInt16 temp1 = 0; sl@0: TInt16 temp2 = 0; sl@0: numResults /= 2; // compensate for bytes to short conversion sl@0: //[print the results to allow analysis] sl@0: for( TInt index = 0; index < numResults; index++ ) sl@0: { sl@0: temp1 = static_cast((*pResults++) &KAndMask8bit); sl@0: temp1 |= static_cast((*pResults++ << 8)); sl@0: sum1 += temp1*temp1; sl@0: temp2 = static_cast((*pRefData++) &KAndMask8bit); sl@0: temp2 |= static_cast((*pRefData++ << 8)); sl@0: sum2 += (temp2-temp1)*(temp2-temp1); sl@0: //INFO_PRINTF3( _L("S %d D %d"),temp2, temp1 ); // add for debugging purposes sl@0: } sl@0: sl@0: //[calculate the ratio ] sl@0: ratio = sum1; sl@0: ratio /=sum2; sl@0: TReal sn = 0.0; sl@0: // calculate as 18db sl@0: Math::Log( sn, ratio ); sl@0: sn *= 10; sl@0: sl@0: INFO_PRINTF2( _L("Signal to Noise Ratio @800Hz %f db"), sn ); sl@0: #ifdef EABI sl@0: if( sn < 18 ) //[ @800hz a sn of less than 18db is deemed a failure sl@0: // not that sn is a great measure of a voice coder's quality] sl@0: result = EFail ; sl@0: #else sl@0: if( sn < 14 ) //DEF086144 - Codec source buffer size is reduced sl@0: result = EFail ; sl@0: #endif sl@0: //[pop data from the cleanup stack ] sl@0: CleanupStack::PopAndDestroy(2, pDecoder); //pDecoder, theCodec, sl@0: delete iRefSrcData; sl@0: iRefSrcData = NULL; sl@0: delete iRefCodedData; sl@0: iRefCodedData = NULL; sl@0: delete iRefDecodedData; sl@0: iRefDecodedData = NULL; sl@0: delete iCodedData; sl@0: iCodedData = NULL; sl@0: delete iDecodedData; sl@0: iDecodedData = NULL; sl@0: sl@0: __MM_HEAP_MARKEND; sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: **/ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0003::DoTestStepPreambleL(void) sl@0: { sl@0: return EPass; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * sl@0: **/ sl@0: TVerdict CTest_MMF_SwCodecDevices_U_0003::DoTestStepPostambleL(void) sl@0: { sl@0: return EPass; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * FillSrcBufferL sl@0: * @param aSrcData pointer to the src data which stores 16bit samples sl@0: * @param aNoSamples number of 16bit samples to store sl@0: * @param aOffset offset used to generate the samples (linear range) sl@0: **/ sl@0: void TLawUtility::FillSrcBufferL( TUint8* aSrcData, TInt aNoSamples, TInt16 aOffset ) sl@0: { sl@0: //[precondition aSrcData != NULL ] sl@0: if( !aSrcData ) sl@0: User::Leave( KErrArgument ); sl@0: const TInt16 KUpperLimit = static_cast(aOffset + aNoSamples); sl@0: TUint8* pDest = aSrcData ; sl@0: for( TInt16 i = aOffset; i< KUpperLimit; i++ ) sl@0: { sl@0: *pDest++ = static_cast( i & 0xff); sl@0: *pDest++ = static_cast( (i >>8) &0xff ); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareCodedData sl@0: * @param aCodedData the data coded using symbian codec sl@0: * @param aRefCodedData the data coded using independent implementation sl@0: * @param aNoSamples the number of coded samples sl@0: * sl@0: **/ sl@0: TInt TLawUtility::CompareCodedDataL(TUint8* aCodedData,TUint8* aRefCodedData, TInt aNoSamples ) sl@0: { sl@0: TInt result = KErrNone; sl@0: //[precondition aCodedData != NULL ] sl@0: if( !aCodedData ) sl@0: User::Leave( KErrArgument); sl@0: //[preciondition aRefCodedData != NULL ] sl@0: if( !aRefCodedData ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: //[ use mem compare to compare the data Buffers ] sl@0: if( Mem::Compare(aCodedData, aNoSamples, aRefCodedData, aNoSamples )!=0) sl@0: { sl@0: //[ data is not the same ] sl@0: for( TInt count = 0; count < aNoSamples; count++ ) sl@0: { sl@0: //RDebug::Print(_L("c1 %u c2 %u"), *aCodedData++, *aRefCodedData++); Statement commented under DEF105143 sl@0: *aCodedData++; sl@0: *aRefCodedData++; sl@0: } sl@0: result = KErrCorrupt; sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * AssembleValL sl@0: * @param aDecodedData sl@0: * @return decoded value sl@0: * sl@0: **/ sl@0: TInt16 TLawUtility::AssembleValL(TUint8* aDecodedData) sl@0: { sl@0: TInt16 val; sl@0: if(!aDecodedData ) sl@0: User::Leave( KErrArgument); sl@0: sl@0: //assemble the value sl@0: val = static_cast( aDecodedData[0] &KAndMask8bit); sl@0: val |= static_cast((aDecodedData[1] << 8 )); sl@0: sl@0: return val; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * SNRatio sl@0: * sl@0: **/ sl@0: TReal TLawUtility::SNRatioL(TUint8* aDecodedData, TUint8* aSrcData, TInt aNoSamples ) sl@0: { sl@0: const TReal KThreshold = 0.0001; sl@0: TReal ratio = 0.0; sl@0: //[precondition aDecodedData != NULL ] sl@0: if( !aDecodedData ) sl@0: User::Leave( KErrArgument ); sl@0: //[ precondition aSrcData != NULL ] sl@0: if( !aSrcData ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: TReal sumSig = 0.0; // numerator sl@0: TReal sumNoise = 0.0; // denominator sl@0: TInt difference = 0; sl@0: TInt16 dataValue = 0; sl@0: TInt decodeVal = 0; sl@0: for( TInt count = 0; count < aNoSamples; count++ ) sl@0: { sl@0: decodeVal = AssembleValL(aDecodedData); sl@0: dataValue = AssembleValL(aSrcData); sl@0: difference = decodeVal - dataValue; sl@0: sumSig += (decodeVal*decodeVal); // sum of the squares of the signal sl@0: sumNoise += (difference * difference ); // sum of the square of the difference sl@0: aDecodedData+=2; sl@0: aSrcData+=2; sl@0: } sl@0: sl@0: //[ guard against division by zero ] sl@0: if( !( sumNoise >= KThreshold )) sl@0: User::Leave( KErrUnderflow ); sl@0: sl@0: //[ calculate the sn ratio ] sl@0: //[ 10log10( sumSig/SumNoise ] sl@0: Math::Log( ratio, (sumSig/sumNoise) ); sl@0: ratio *= 10; // ratio = 10*log( x**2/(error**2)) in db sl@0: return ratio; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareSNRatiosL sl@0: * @param aCodecSN codec under test SN ratio in db sl@0: * @param aCodecSN2 refernce codec SN ratio in db sl@0: * @param aThreshold difference allowed in db sl@0: * @result within tolerance sl@0: * sl@0: **/ sl@0: TBool TLawUtility::CompareSNRatiosL( TReal aCodecSN, TReal aCodecSN2, TReal aTolerance ) sl@0: { sl@0: TBool result = ETrue; sl@0: TReal difference = (aCodecSN - aCodecSN2); sl@0: //[ it would be nice to replace this with a abs function ?] sl@0: if( difference < 0.0 ) sl@0: { sl@0: if( aTolerance > difference ) sl@0: { sl@0: result = EFalse; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if( aTolerance < difference ) sl@0: { sl@0: result = EFalse; sl@0: } sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ComputeSNL compute the Signal to Noise Ratio sl@0: * sl@0: **/ sl@0: TReal TLawUtility::ComputeSNL( TReal aSumSigSquared, TReal aSumErrorSquared ) sl@0: { sl@0: TReal sn = 0.0; sl@0: const TReal tolerance = 0.001; sl@0: //[precondition error is >= tolerance ] sl@0: if( aSumErrorSquared < tolerance ) sl@0: User::Leave( KErrArgument ); sl@0: //[claculate ratio safely ] sl@0: Math::Log( sn, (aSumSigSquared/aSumErrorSquared)); sl@0: sn*= 10; sl@0: return sn; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * SumSquaredL sl@0: * sl@0: **/ sl@0: TReal TLawUtility::SumSquaredL( TUint8* aData, TInt aNoSamples ) sl@0: { sl@0: //[precondition arg is ok ] sl@0: if( !aData ) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: TUint8* pData = aData; sl@0: TInt16 sample ; sl@0: TReal sumSigSquared = 0.0; sl@0: for( TInt count = 0; count < aNoSamples; count++ ) sl@0: { sl@0: sample = static_cast( pData[0] &KAndMask8bit); sl@0: sample |= static_cast((pData[1] << 8 )); sl@0: sumSigSquared += (sample*sample); sl@0: pData+=2; sl@0: } sl@0: sl@0: return sumSigSquared; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * SumErrorSquaredL sl@0: * @param aData sl@0: * @param aData2 sl@0: * @param aNoSamples sl@0: * @result TReal sl@0: * sl@0: **/ sl@0: TReal TLawUtility::SumErrorSquaredL( TUint8* aData, TUint8* aData2, TInt aNoSamples ) sl@0: { sl@0: //[precondition aData is not NULL] sl@0: if( !aData ) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: //[precondition aData2 is not NULL ] sl@0: if( !aData2 ) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: TUint8* pData = aData; sl@0: TUint8* pData2 = aData2; sl@0: TInt16 sample ; sl@0: TInt16 sample2; sl@0: TReal sumErrorSquared = 0.0; sl@0: TInt error; sl@0: for( TInt count = 0; count < aNoSamples; count++ ) sl@0: { sl@0: error = 0; sl@0: sample = static_cast( pData[0] &KAndMask8bit); sl@0: sample |= static_cast((pData[1] << 8 )); sl@0: sample2 = static_cast( pData2[0] &KAndMask8bit); sl@0: sample2 |= static_cast((pData2[1] << 8 )); sl@0: error = sample -sample2; // compute the error sl@0: sumErrorSquared += (error*error); // add error squared to the sum sl@0: pData +=2; sl@0: pData2 +=2; sl@0: } sl@0: sl@0: return sumErrorSquared; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CTestMuLawCodec_U_0006 sl@0: * sl@0: **/ sl@0: CTestMuLawCodec_U_0006::CTestMuLawCodec_U_0006() sl@0: { sl@0: //[ set test name] sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0006-HP"); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * LinearToMuLawSample sl@0: * @param aSample a 16 bit pcm sample sl@0: * @result Mu Law encoded sample sl@0: * sl@0: **/ sl@0: TUint8 CTestMuLawCodec_U_0006::LinearToMuLawSample( TInt16 aSample) sl@0: { sl@0: const int KBias = 0x84; sl@0: const int KClip = 32635; sl@0: TInt sign = (aSample >> 8) & 0x80; sl@0: if(sign) sl@0: aSample = static_cast(-aSample); sl@0: if(aSample > KClip) sl@0: aSample = KClip; sl@0: aSample = static_cast(aSample + KBias); sl@0: TInt exponent = static_cast( MuLawCompressTable[(aSample>>7) & 0xFF]); sl@0: TInt mantissa = (aSample >> (exponent+3)) & 0x0F; sl@0: TInt compressedByte = ~(sign | (exponent << 4) | mantissa); sl@0: return static_cast( compressedByte ); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConvertPcmMuLaw sl@0: * sl@0: **/ sl@0: void CTestMuLawCodec_U_0006::ConvertPcmMuLawL(TUint8* aSrcData, TUint8* aCodedData, TInt aNumSamples ) sl@0: { sl@0: //[ precondition aSrcData ] sl@0: if( !aSrcData ) sl@0: User::Leave( KErrArgument ); sl@0: //[precondition aCodedData ] sl@0: if( !aCodedData ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: TUint8* pCoded = aCodedData; sl@0: TUint8* pData = aSrcData ; sl@0: TInt16 pcmSample; sl@0: for( TInt count = 0; count < aNumSamples; count++ ) sl@0: { sl@0: //[ code the data ] sl@0: pcmSample = static_cast(pData[0]); sl@0: pcmSample |= static_cast((pData[1] << 8 )); sl@0: *pCoded++ = LinearToMuLawSample(pcmSample); sl@0: pData+=2; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConvertMuLawPcm sl@0: * sl@0: **/ sl@0: void CTestMuLawCodec_U_0006::ConvertMuLawPcmL(TUint8* aCoded, TUint8* aDecoded, TInt aNumSamples ) sl@0: { sl@0: //[ precondition aCoded ] sl@0: if( !aCoded ) sl@0: User::Leave( KErrArgument ); sl@0: //[precondition aDecoded ] sl@0: if( !aDecoded ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: TInt16 pcmSample; sl@0: TUint8* pCoded = aCoded; sl@0: TUint8* pDecoded = aDecoded; sl@0: //[ lets convert the data ] sl@0: for(TInt count = 0; count < aNumSamples; count++ ) sl@0: { sl@0: pcmSample = MuLawDecompressTable[*pCoded++]; sl@0: *pDecoded++ = static_cast( pcmSample & 0xFF); sl@0: *pDecoded++ = static_cast((pcmSample >> 8 ) & 0xFF); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: **/ sl@0: TVerdict CTestMuLawCodec_U_0006::DoTestStepL() sl@0: { sl@0: TVerdict result = EPass; sl@0: const TInt KSrcBufferSize = 400; // small buffer size sl@0: const TInt KHalfSrcBufferSize = 200; // small buffer size sl@0: const TInt KCodedBufferSize = 200; // small buffer size sl@0: const TInt KLowerLimit = -800; //lower limit of test range sl@0: const TInt KUpperLimit = 800; // upper limit of test range +1 sl@0: sl@0: //[ allocate memory buffers] sl@0: TUint8* pSymbianSrcData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pSymbianSrcData); sl@0: TUint8* pIndependentSrcData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pIndependentSrcData); sl@0: TUint8* pSymbianCodedData = new(ELeave)TUint8[KCodedBufferSize]; sl@0: CleanupStack::PushL(pSymbianCodedData); sl@0: TUint8* pIndependentCodedData = new(ELeave)TUint8[KCodedBufferSize]; sl@0: CleanupStack::PushL(pIndependentCodedData); sl@0: TUint8* pSymbianDecodedData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pSymbianDecodedData); sl@0: TUint8* pIndependentDecodedData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pIndependentDecodedData); sl@0: sl@0: TMMFAudioMuLawToS16PcmCodec decoder; sl@0: TMMFAudioSPcm16ToMuLawCodec encoder; sl@0: sl@0: TLawUtility helper; sl@0: TReal symbianCodecSN = 0.0; sl@0: TReal independentCodecSN = 0.0; sl@0: sl@0: TReal sumRefSig = 0.0; // sum of sig squared sl@0: TReal sumRefError = 0.0; // sum of error sig squared sl@0: TReal sumSymbianSig = 0.0; // sum of sig squared sl@0: TReal sumSymbianError = 0.0; // sum of error sig squared sl@0: sl@0: //[ interate over a suitable range and process each buffer] sl@0: for( TInt index = KLowerLimit; index < KUpperLimit; index+= KHalfSrcBufferSize ) sl@0: { sl@0: TInt16 offset = static_cast( index); sl@0: //[ fill the src buffers ] sl@0: helper.FillSrcBufferL( pSymbianSrcData, KHalfSrcBufferSize, offset ); sl@0: helper.FillSrcBufferL( pIndependentSrcData, KHalfSrcBufferSize, offset ); sl@0: sl@0: //[encode the src data ] sl@0: encoder.Convert( pSymbianSrcData, pSymbianCodedData, KHalfSrcBufferSize ); sl@0: ConvertPcmMuLawL(pIndependentSrcData,pIndependentCodedData,KHalfSrcBufferSize ); sl@0: sl@0: //[ decode the data ] sl@0: decoder.Convert( pSymbianCodedData, pSymbianDecodedData, KHalfSrcBufferSize ); sl@0: ConvertMuLawPcmL( pIndependentCodedData,pIndependentDecodedData,KHalfSrcBufferSize); sl@0: sl@0: //[ check both codecs code the data similarly] sl@0: TInt errorCode =helper.CompareCodedDataL(pIndependentCodedData, pSymbianCodedData, KHalfSrcBufferSize ); sl@0: if( errorCode != KErrNone ) sl@0: { sl@0: INFO_PRINTF1(_L("Forward Transformation for Mu-Law codec is not conformant to ref codec")); sl@0: User::LeaveIfError(errorCode); sl@0: } sl@0: //[ upate running total sums to be used for signal to noise sl@0: // ratio calculations ] sl@0: sumRefSig += helper.SumSquaredL(pIndependentSrcData, KHalfSrcBufferSize); sl@0: sumRefError += helper.SumErrorSquaredL(pIndependentSrcData,pIndependentDecodedData,KHalfSrcBufferSize); sl@0: sumSymbianSig += helper.SumSquaredL(pSymbianSrcData,KHalfSrcBufferSize); sl@0: sumSymbianError += helper.SumErrorSquaredL(pSymbianSrcData,pSymbianDecodedData,KHalfSrcBufferSize); sl@0: } sl@0: sl@0: const TReal KTolerance = 1; // allow for a 1 db tolerance sl@0: symbianCodecSN = helper.ComputeSNL(sumSymbianSig,sumSymbianError); sl@0: independentCodecSN = helper.ComputeSNL(sumRefSig, sumRefError); sl@0: // Gamma = (dynamic range of codec /signal std deviation ) sl@0: INFO_PRINTF1(_L("We would expect S/N ration to be greater than 35db for an MuLaw codec with Gamma = 10")); sl@0: INFO_PRINTF2(_L("Signal/Noise Ratio Symbian Codec %f"), symbianCodecSN ); sl@0: INFO_PRINTF2(_L("Signal/Noise Ratio Reference Codec %f"), independentCodecSN ); sl@0: sl@0: //[ compare the s/n ratio's of the two codec implementations] sl@0: if( !helper.CompareSNRatiosL( symbianCodecSN, independentCodecSN, KTolerance )) sl@0: { sl@0: //[ fail the test because the s/n ratios were divergent ] sl@0: result = EFail; sl@0: } sl@0: CleanupStack::PopAndDestroy(6,pSymbianSrcData); //pSymbianSrcData,pIndependentSrcData, sl@0: //pSymbianCodedData,pIndependentCodedData sl@0: //pSymbianDecodedData,pIndependentDecodedData sl@0: sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestMuLawCodec_U_0006::DoTestStepPreambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: return result; //nothing doing sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestMuLawCodec_U_0006::DoTestStepPostambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: return result; //nothing doing sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Mu-Law Compression Table sl@0: * sl@0: **/ sl@0: const TInt8 CTestMuLawCodec_U_0006::MuLawCompressTable[PcmToMuLawCompressionTableSize] = sl@0: { sl@0: 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, sl@0: 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, sl@0: 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, sl@0: 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, sl@0: 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 sl@0: }; sl@0: sl@0: /** sl@0: * sl@0: * Mu-Law Decompression Table sl@0: * sl@0: **/ sl@0: const TInt16 CTestMuLawCodec_U_0006::MuLawDecompressTable[MuLawToPcmCompressionTableSize]= sl@0: { sl@0: -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, sl@0: -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, sl@0: -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, sl@0: -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, sl@0: -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, sl@0: -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, sl@0: -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, sl@0: -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, sl@0: -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, sl@0: -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, sl@0: -876, -844, -812, -780, -748, -716, -684, -652, sl@0: -620, -588, -556, -524, -492, -460, -428, -396, sl@0: -372, -356, -340, -324, -308, -292, -276, -260, sl@0: -244, -228, -212, -196, -180, -164, -148, -132, sl@0: -120, -112, -104, -96, -88, -80, -72, -64, sl@0: -56, -48, -40, -32, -24, -16, -8, 0, sl@0: 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, sl@0: 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, sl@0: 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, sl@0: 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, sl@0: 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, sl@0: 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, sl@0: 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, sl@0: 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, sl@0: 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, sl@0: 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, sl@0: 876, 844, 812, 780, 748, 716, 684, 652, sl@0: 620, 588, 556, 524, 492, 460, 428, 396, sl@0: 372, 356, 340, 324, 308, 292, 276, 260, sl@0: 244, 228, 212, 196, 180, 164, 148, 132, sl@0: 120, 112, 104, 96, 88, 80, 72, 64, sl@0: 56, 48, 40, 32, 24, 16, 8, 0 sl@0: }; sl@0: sl@0: /** sl@0: * sl@0: * CTestALawCodec_U_0004 sl@0: * sl@0: **/ sl@0: CTestALawCodec_U_0004::CTestALawCodec_U_0004() sl@0: { sl@0: //[ set test name ] sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0004-HP"); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConvertPcmALaw converts Pcm 16 to 8bit ALaw sl@0: * @param aSrcData The src data sl@0: * @param aCoded The coded result sl@0: * @param aNumSamples The number of samples to be processed sl@0: * @precondition aSrcData is not NULL sl@0: * @precondition aCodedData is not NULL sl@0: * @precondition there is sufficient room in the destination sl@0: * to contain the coded samples sl@0: * sl@0: **/ sl@0: void CTestALawCodec_U_0004::ConvertPcmALawL(TUint8* aSrcData, TUint8* aCodedData, TInt aNumSamples ) sl@0: { sl@0: //[ precondition aSrcData ] sl@0: if( !aSrcData ) sl@0: User::Leave( KErrArgument ); sl@0: //[precondition aCodedData ] sl@0: if( !aCodedData ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: TUint8* pCoded = aCodedData; sl@0: TUint8* pData = aSrcData ; sl@0: TInt16 pcmSample; sl@0: for( TInt count = 0; count < aNumSamples; count++ ) sl@0: { sl@0: //[ code the data ] sl@0: pcmSample = static_cast(pData[0]); sl@0: pcmSample |= static_cast((pData[1] << 8 )); sl@0: *pCoded++ = LinearToALawSample(pcmSample); sl@0: pData+=2; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * ConvertALawPcm converts from 8bit ALaw to Pcm16 sl@0: * @param aCoded The coded data sl@0: * @param aDecoded The decoded result sl@0: * @param aNumSamples The number of samples to be processed sl@0: * @precondition aCoded is not NULL sl@0: * @precondition aDecoded is not NULL sl@0: * @precondition there is sufficient room in the destination sl@0: * to contain the coded samples sl@0: * sl@0: **/ sl@0: void CTestALawCodec_U_0004::ConvertALawPcmL(TUint8* aCoded, TUint8* aDecoded, TInt aNumSamples ) sl@0: { sl@0: //[ precondition aSrcData ] sl@0: if( !aCoded ) sl@0: User::Leave( KErrArgument ); sl@0: //[precondition aCodedData ] sl@0: if( !aDecoded ) sl@0: User::Leave( KErrArgument ); sl@0: sl@0: TInt16 pcmSample; sl@0: TUint8* pCoded = aCoded; sl@0: TUint8* pDecoded = aDecoded; sl@0: //[ lets convert the data ] sl@0: for(TInt count = 0; count < aNumSamples; count++ ) sl@0: { sl@0: pcmSample = ALawDecompressTable[*pCoded++]; sl@0: *pDecoded++ = static_cast(pcmSample & 0xFF); sl@0: *pDecoded++ = static_cast((pcmSample >> 8 ) & 0xFF); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * LinearToALawSample converts a Pcm16 sample to ALaw sl@0: * @param aSample the PCM 16 sample to be converted sl@0: * @result coded result sl@0: * sl@0: **/ sl@0: TUint8 CTestALawCodec_U_0004::LinearToALawSample(TInt16 aSample) sl@0: { sl@0: const TInt KClip = 32635; sl@0: TInt sign; sl@0: TInt exponent; sl@0: TInt mantissa; sl@0: TUint8 compressedByte; sl@0: sign = ((~aSample) >> 8) & 0x80; sl@0: if(!sign) sl@0: aSample = static_cast(-aSample); sl@0: if(aSample > KClip) sl@0: aSample = KClip; sl@0: if(aSample >= 256) sl@0: { sl@0: exponent = static_cast( ALawCompressTable[(aSample >> 8) & 0x7F]); sl@0: mantissa = (aSample >> (exponent + 3) ) & 0x0F; sl@0: compressedByte = static_cast ((exponent << 4) | mantissa); sl@0: } sl@0: else sl@0: { sl@0: compressedByte = static_cast (aSample >> 4); sl@0: } sl@0: compressedByte ^= (sign ^ 0x55); sl@0: return compressedByte; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: **/ sl@0: TVerdict CTestALawCodec_U_0004::DoTestStepL() sl@0: { sl@0: TVerdict result = EPass; sl@0: const TInt KSrcBufferSize = 400; // small buffer size sl@0: const TInt KHalfSrcBufferSize = 200; // small buffer size sl@0: const TInt KCodedBufferSize = 200; // small buffer size sl@0: const TInt KLowerLimit = -400; //lower limit of test range sl@0: const TInt KUpperLimit = 400; // upper limit of test range +1 sl@0: sl@0: //[ allocate memory buffers] sl@0: TUint8* pSymbianSrcData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pSymbianSrcData); sl@0: TUint8* pIndependentSrcData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pIndependentSrcData); sl@0: TUint8* pSymbianCodedData = new(ELeave)TUint8[KCodedBufferSize]; sl@0: CleanupStack::PushL(pSymbianCodedData); sl@0: TUint8* pIndependentCodedData = new(ELeave)TUint8[KCodedBufferSize]; sl@0: CleanupStack::PushL(pIndependentCodedData); sl@0: TUint8* pSymbianDecodedData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pSymbianDecodedData); sl@0: TUint8* pIndependentDecodedData = new(ELeave)TUint8[KSrcBufferSize]; sl@0: CleanupStack::PushL(pIndependentDecodedData); sl@0: sl@0: TMMFAudioSPcm16ToAlawCodec encoder; sl@0: TMMFAudioALawToS16PcmCodec decoder; sl@0: sl@0: TLawUtility helper; sl@0: TReal symbianCodecSN = 0.0; sl@0: TReal independentCodecSN = 0.0; sl@0: sl@0: TReal sumRefSig = 0.0; // sum of sig squared sl@0: TReal sumRefError = 0.0; // sum of error sig squared sl@0: TReal sumSymbianSig = 0.0; // sum of sig squared sl@0: TReal sumSymbianError = 0.0; // sum of error sig squared sl@0: sl@0: //[ interate over a suitable range and process each buffer] sl@0: for( TInt index = KLowerLimit; index < KUpperLimit; index+= KHalfSrcBufferSize ) sl@0: { sl@0: TInt16 offset = static_cast( index); sl@0: //[ fill the src buffers ] sl@0: helper.FillSrcBufferL( pSymbianSrcData, KHalfSrcBufferSize, offset ); sl@0: helper.FillSrcBufferL( pIndependentSrcData, KHalfSrcBufferSize, offset ); sl@0: sl@0: //[encode the src data ] sl@0: encoder.Convert( pSymbianSrcData, pSymbianCodedData, KHalfSrcBufferSize ); sl@0: ConvertPcmALawL(pIndependentSrcData,pIndependentCodedData,KHalfSrcBufferSize ); sl@0: sl@0: //[ decode the data ] sl@0: decoder.Convert( pSymbianCodedData, pSymbianDecodedData, KHalfSrcBufferSize ); sl@0: ConvertALawPcmL( pIndependentCodedData,pIndependentDecodedData,KHalfSrcBufferSize); sl@0: sl@0: //[ check both codecs code the data similarly] sl@0: TInt errorCode = helper.CompareCodedDataL(pIndependentCodedData, pSymbianCodedData, KHalfSrcBufferSize ); sl@0: if( errorCode != KErrNone ) sl@0: { sl@0: INFO_PRINTF1(_L("Forward Transformation for ALaw codec is not conformant to ref codec")); sl@0: User::LeaveIfError(errorCode); sl@0: } sl@0: sl@0: //[ upate running total sums to be used for signal to noise sl@0: // ratio calculations ] sl@0: sumRefSig += helper.SumSquaredL(pIndependentSrcData, KHalfSrcBufferSize); sl@0: sumRefError += helper.SumErrorSquaredL(pIndependentSrcData,pIndependentDecodedData,KHalfSrcBufferSize); sl@0: sumSymbianSig += helper.SumSquaredL(pSymbianSrcData,KHalfSrcBufferSize); sl@0: sumSymbianError += helper.SumErrorSquaredL(pSymbianSrcData,pSymbianDecodedData,KHalfSrcBufferSize); sl@0: } sl@0: const TReal KTolerance = 1; // allow for a 1 db tolerance sl@0: symbianCodecSN = helper.ComputeSNL(sumSymbianSig,sumSymbianError); sl@0: independentCodecSN = helper.ComputeSNL(sumRefSig, sumRefError); sl@0: // Gamma = (dynamic range of codec /signal std deviation ) sl@0: INFO_PRINTF1(_L("We would expect S/N ration to be greater than 30db for an ALaw codec with Gamma = 10")); sl@0: INFO_PRINTF2(_L("Signal/Noise Ratio Symbian Codec %f"), symbianCodecSN ); sl@0: INFO_PRINTF2(_L("Signal/Noise Ratio Reference Codec %f"), independentCodecSN ); sl@0: sl@0: //[ compare the s/n ratio's of the two codec implementations] sl@0: if( !helper.CompareSNRatiosL( symbianCodecSN, independentCodecSN, KTolerance )) sl@0: { sl@0: //[ fail the test because the s/n ratios were divergent ] sl@0: result = EFail; sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(6,pSymbianSrcData); //pSymbianSrcData,pIndependentSrcData, sl@0: //pSymbianCodedData,pIndependentCodedData sl@0: //pSymbianDecodedData,pIndependentDecodedData sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestALawCodec_U_0004::DoTestStepPreambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: return result; //nothing doing sl@0: } sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestALawCodec_U_0004::DoTestStepPostambleL(void) sl@0: { sl@0: TVerdict result = EPass; sl@0: return result; //nothing doing sl@0: } sl@0: /** sl@0: * sl@0: * ALaw Compression Table sl@0: * sl@0: **/ sl@0: const TInt8 CTestALawCodec_U_0004::ALawCompressTable[PcmToALawCompressionTableSize] = sl@0: { sl@0: 1,1,2,2,3,3,3,3, sl@0: 4,4,4,4,4,4,4,4, sl@0: 5,5,5,5,5,5,5,5, sl@0: 5,5,5,5,5,5,5,5, sl@0: 6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6, sl@0: 6,6,6,6,6,6,6,6, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7, sl@0: 7,7,7,7,7,7,7,7 sl@0: }; sl@0: sl@0: /** sl@0: * sl@0: * ALaw Decompression Table sl@0: * sl@0: **/ sl@0: const TInt16 CTestALawCodec_U_0004::ALawDecompressTable[ALawToPcmCompressionTableSize] = sl@0: { sl@0: -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, sl@0: -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, sl@0: -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, sl@0: -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, sl@0: -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, sl@0: -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, sl@0: -11008,-10496,-12032,-11520,-8960, -8448, -9984, -9472, sl@0: -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, sl@0: -344, -328, -376, -360, -280, -264, -312, -296, sl@0: -472, -456, -504, -488, -408, -392, -440, -424, sl@0: -88, -72, -120, -104, -24, -8, -56, -40, sl@0: -216, -200, -248, -232, -152, -136, -184, -168, sl@0: -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, sl@0: -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, sl@0: -688, -656, -752, -720, -560, -528, -624, -592, sl@0: -944, -912, -1008, -976, -816, -784, -880, -848, sl@0: 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, sl@0: 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, sl@0: 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, sl@0: 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, sl@0: 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, sl@0: 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, sl@0: 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, sl@0: 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, sl@0: 344, 328, 376, 360, 280, 264, 312, 296, sl@0: 472, 456, 504, 488, 408, 392, 440, 424, sl@0: 88, 72, 120, 104, 24, 8, 56, 40, sl@0: 216, 200, 248, 232, 152, 136, 184, 168, sl@0: 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, sl@0: 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, sl@0: 688, 656, 752, 720, 560, 528, 624, 592, sl@0: 944, 912, 1008, 976, 816, 784, 880, 848 sl@0: }; sl@0: sl@0: /** sl@0: * sl@0: * CTestIMaadCodec sl@0: * sl@0: **/ sl@0: CTestIMaadCodec::CTestIMaadCodec() sl@0: { sl@0: //[ set test name ] sl@0: iTestStepName = _L("MM-MMF-SWCODECDEVICES-U-0022-HP"); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepL sl@0: * sl@0: **/ sl@0: TVerdict CTestIMaadCodec::DoTestStepL() sl@0: { sl@0: __MM_HEAP_MARK; sl@0: TVerdict result = EPass; sl@0: TInt srcBufferSize; sl@0: TInt sinkBufferSize; sl@0: const TReal KExpectedSNRatioDb = 30.0; //30 db for now sl@0: sl@0: //[ Create coder and decoder codecs ] sl@0: CMMFPcm16ToImaAdpcmHwDevice* pHwDevice = CMMFPcm16ToImaAdpcmHwDevice::NewL(); sl@0: CleanupStack::PushL( pHwDevice ); sl@0: sl@0: CMMFSwCodec& theCodec = pHwDevice->Codec(); sl@0: sl@0: CMMFImaAdpcmToPcm16CodecHwDevice* pHwDecoder = CMMFImaAdpcmToPcm16CodecHwDevice::NewL(); sl@0: CleanupStack::PushL( pHwDecoder ); sl@0: sl@0: CMMFSwCodec& theDecoder = pHwDecoder->Codec(); sl@0: sl@0: //[ Create data buffers with position != 0] sl@0: srcBufferSize = 100; // arbitrary non zero size sl@0: sinkBufferSize = 100; sl@0: CMMFDescriptorBuffer* pSrcBuffer = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: CleanupStack::PushL( pSrcBuffer ); sl@0: sl@0: CMMFDescriptorBuffer* pSinkBuffer = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: CleanupStack::PushL( pSinkBuffer ); sl@0: sl@0: //[ trap & check error code ] sl@0: TInt errCode; sl@0: pSrcBuffer->Data().SetLength(srcBufferSize); sl@0: pSinkBuffer->Data().SetLength(sinkBufferSize); sl@0: pSrcBuffer->SetPosition(1); sl@0: TRAP( errCode, theCodec.ProcessL(*pSrcBuffer, *pSinkBuffer)); sl@0: if( errCode != KErrArgument ) sl@0: { sl@0: result = EFail; sl@0: return result; sl@0: } sl@0: sl@0: //[set position of sink buffer to nonzero value] sl@0: pSrcBuffer->SetPosition(0); sl@0: pSinkBuffer->SetPosition(1); sl@0: TRAP( errCode, theCodec.ProcessL(*pSrcBuffer, *pSinkBuffer)); sl@0: if( errCode != KErrArgument ) sl@0: { sl@0: result = EFail; sl@0: return result; sl@0: } sl@0: sl@0: //[set position of sink and src to nonzero value ] sl@0: pSrcBuffer->SetPosition(1); sl@0: pSinkBuffer->SetPosition(1); sl@0: TRAP( errCode, theCodec.ProcessL(*pSrcBuffer, *pSinkBuffer)); sl@0: if( errCode != KErrArgument ) sl@0: { sl@0: result = EFail; sl@0: return result; sl@0: } sl@0: sl@0: //[ reset the position of both buffers to zero ] sl@0: pSrcBuffer->SetPosition(0); sl@0: pSinkBuffer->SetPosition(0); sl@0: //[ set the src/sink buffer sizes to src and sink sl@0: // buffer sizes and fill src with data ] sl@0: CleanupStack::PopAndDestroy(2, pSrcBuffer); // pSrcBuffer, pSinkBuffer sl@0: sl@0: //[Create Source & Sink and fill source data in ] sl@0: srcBufferSize = theCodec.SourceBufferSize(); sl@0: pSrcBuffer = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: CleanupStack::PushL( pSrcBuffer ); sl@0: sl@0: CMMFDescriptorBuffer* pDecodedBuffer = CMMFDescriptorBuffer::NewL( srcBufferSize ); sl@0: CleanupStack::PushL( pDecodedBuffer ); sl@0: sl@0: sinkBufferSize = theCodec.SinkBufferSize(); sl@0: pSinkBuffer = CMMFDescriptorBuffer::NewL( sinkBufferSize ); sl@0: CleanupStack::PushL( pSinkBuffer ); sl@0: sl@0: pSrcBuffer->Data().SetLength(srcBufferSize); sl@0: pDecodedBuffer->Data().SetLength(srcBufferSize); sl@0: pSinkBuffer->Data().SetLength(sinkBufferSize); sl@0: sl@0: //[ fill src buffer with ramp] sl@0: FillSrcBufferL( *pSrcBuffer ); sl@0: // encode and decode the data sl@0: theCodec.ProcessL(*pSrcBuffer, *pSinkBuffer); sl@0: theDecoder.ProcessL( *pSinkBuffer, *pDecodedBuffer ); sl@0: sl@0: if(!CompareResults( KExpectedSNRatioDb, pSrcBuffer, pDecodedBuffer)) sl@0: { sl@0: //Test has failed because sn ratio was not good enough sl@0: result = EFail; sl@0: } sl@0: sl@0: //[ clean up ] sl@0: CleanupStack::PopAndDestroy( 5, pHwDevice ); // pHwDevice, pHwDecoder, pSrcBuffer, pDecodedBuffer, pSinkBuffer sl@0: sl@0: __MM_HEAP_MARKEND; sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPreambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestIMaadCodec::DoTestStepPreambleL(void) sl@0: { sl@0: return EPass; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * DoTestStepPostambleL sl@0: * sl@0: **/ sl@0: TVerdict CTestIMaadCodec::DoTestStepPostambleL(void) sl@0: { sl@0: return EPass; sl@0: } sl@0: sl@0: sl@0: /** sl@0: * sl@0: * FillSrcBuffer sl@0: * @param aBuffer sl@0: * This function fills the buffer with a ramp of linear pcm16 data sl@0: * sl@0: **/ sl@0: void CTestIMaadCodec::FillSrcBufferL( CMMFDescriptorBuffer& aBuffer ) sl@0: { sl@0: TInt slope = 2; sl@0: TInt dataLength = aBuffer.Data().Length(); sl@0: TUint8* pData = const_cast(aBuffer.Data().Ptr()); sl@0: TInt noPc16Samples = dataLength/2; sl@0: ASSERT( noPc16Samples*slope < 32768 ); sl@0: for( TInt16 count = 0; count < noPc16Samples ; count++ ) sl@0: { sl@0: TInt16 pcmSample = static_cast( count * slope); sl@0: *pData++ = static_cast( pcmSample & 0xFF ); sl@0: *pData++ = static_cast( ( pcmSample >> 8 )); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * CompareResults sl@0: * @param aExpectedSNRatioDb sl@0: * @param aSrcBuffer sl@0: * @param aSinkBuffer sl@0: * @result TBool sl@0: * This function returns True if the computed Signal to Noise Ratio sl@0: * is Greater than or equal to the expected signal to noise ratio. sl@0: * The function will also return EFalse if any of the preconditions sl@0: * are violated. sl@0: * @precondition aSrcBuffer, aSinkBuffer are not NULL sl@0: * @precondition aSrcBuffer data lenegth == aSinkBuffer data length sl@0: * @precondition the data buffers contain pcm16 data sl@0: * sl@0: **/ sl@0: TBool CTestIMaadCodec::CompareResults( TReal aExpectedSNRatioDb, sl@0: CMMFDescriptorBuffer* aSrcBuffer, sl@0: CMMFDescriptorBuffer* aSinkBuffer) sl@0: { sl@0: TBool result = EFalse; sl@0: sl@0: //[ precondition pointers are not NULL ] sl@0: if( !aSrcBuffer || !aSinkBuffer ) sl@0: return result; sl@0: sl@0: //[ precondition buffer lengths are equal ] sl@0: TInt length = aSrcBuffer->Data().Length(); sl@0: if( length != aSinkBuffer->Data().Length() ) sl@0: return result; sl@0: sl@0: // buffers must be of even length sl@0: if( !(length % sizeof(TInt16) == 0 )) sl@0: return result; sl@0: sl@0: TInt pcmLength = length/2; sl@0: TReal sumSignalSquared = 0.0; sl@0: TReal sumNoiseSquared = 0.0; sl@0: TUint8* pSrcData = const_cast(aSrcBuffer->Data().Ptr()); sl@0: TUint8* pDecodeData = const_cast(aSinkBuffer->Data().Ptr()); sl@0: TInt16 sampleOriginal; sl@0: TInt16 sampleDecode; sl@0: for( TInt count = 0; count < pcmLength; count++ ) sl@0: { sl@0: sampleOriginal = static_cast( pSrcData[0] &KAndMask8bit); sl@0: sampleOriginal |= static_cast((pSrcData[1] << 8 )); sl@0: sampleDecode = static_cast( pDecodeData[0] &KAndMask8bit); sl@0: sampleDecode |= static_cast((pDecodeData[1] << 8 )); sl@0: pSrcData+=2; sl@0: pDecodeData+= 2; sl@0: sumSignalSquared += sampleOriginal * sampleOriginal; sl@0: TInt noise = sampleOriginal - sampleDecode ; sl@0: sumNoiseSquared += noise * noise; sl@0: } sl@0: sl@0: //[ if the noise is low the signals are equivalent and sl@0: // overflow can be avoided ] sl@0: if( sumNoiseSquared < 0.001 ) sl@0: { sl@0: result = ETrue; sl@0: return result; sl@0: } sl@0: TReal computedSNRatioDb; sl@0: Math::Log( computedSNRatioDb, sumSignalSquared/sumNoiseSquared ); sl@0: computedSNRatioDb *= 10; sl@0: sl@0: //[ compare claculated s/n ratio against expected ] sl@0: if( computedSNRatioDb >= aExpectedSNRatioDb ) sl@0: result = ETrue; sl@0: sl@0: return result; sl@0: }