Update contrib.
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
22 // Test system includes
23 #include "tsu_mmf_CodecTests.h"
24 #include "TSU_MMF_DeviceSuite.h"
27 #include <mmf/plugin/mmfhwdeviceimplementationuids.hrh>
28 #include "MmfPcm16toAlawhwDevice.h"
29 #include "MmfALawToPcm16HwDevice.h"
30 #include "mmfpcm16toMulawhwdevice.h"
31 #include "MmfMuLawToPcm16hwDevice.h"
32 #include "mmfpcmS8ToPcmS16HwDevice.h"
33 #include "mmfpcmS16PcmS8HwDevice.h"
34 #include "mmfpcm16topcmU16BEHwDevice.h"
35 #include "mmfpcm16SwapEndianhwdevice.h"
36 #include "mmfpcm16ToImaAdpcm.h"
37 #include "MmfImaAdpcmtopcm16hwdevice.h"
38 #include "MMFpcm16ToPcm16HwDevice.h"
39 #include "MMFpcm16ToPcmU8HwDevice.h"
40 #include "MMFpcmU8ToPcm16HwDevice.h"
41 #include "mmfpcmS16PcmS8HwDevice.h"
43 const TInt KFmtChunkSize = 16;
44 const TInt KAuMagic = 0x2e736e64;
46 //[ Codec Unit tests structure
47 // The unit tests shall use text files
48 // for small portions of test data
49 // which should be stored are stored in a simple format
50 // containing the relevant parameters for the test
52 class TCodecUnitTestParams
55 const TText* iTestName; // name of the test
56 const TText* iInputFilename; // input wav file
57 const TText* iComparisonFileName; // output wav file
58 TInt iExpectedResult; // expected result
61 // constant table of parameters for tests
62 const TCodecUnitTestParams KTestParameters[] =
65 _S("MM-MMF-SWCODECDEVICES-U-0010-HP"),
66 _S("Pcm16Mono8khz400hzTone.wav"),
67 _S("Pcm16BMono8Khz400hzTone.Au"),
72 _S("MM-MMF-SWCODECDEVICES-U-0011-HP"),
73 _S("Pcm16Mono8khz400hzTone.wav"),
74 _S("Imaad4BitMono8Khz400hzTone.wav"),
79 _S("MM-MMF-SWCODECDEVICES-U-0012-HP"),
80 _S("Imaad4BitMono8Khz400hzTone.wav"),
81 _S("Pcm16Mono8khz400hzTone.wav"),
86 _S("MM-MMF-SWCODECDEVICES-U-0014-HP"),
87 _S("Pcm16Mono8khz400hzTone.wav"),
88 _S("PcmU8Mono8khz400hzTone.wav"),
93 _S("MM-MMF-SWCODECDEVICES-U-0015-HP"),
94 _S("PcmU8Mono8khz400hzTone.wav"),
95 _S("Pcm16Mono8khz400hzTone.wav"),
100 _S("MM-MMF-SWCODECDEVICES-U-0016-HP"),
101 _S("Pcm16Stereo8khz400hzTone.wav"),
102 _S("PcmU8Stereo8khz400hzTone.wav"),
110 * @param aRefCodedData
115 template <class T, class Comparator, TInt A, TInt B, TInt C>
116 void CTestStepCodecUnitTest<T,Comparator, A, B, C>::Print8BitResults( TUint8* aRefCodedData, TUint8* aCodedData, TInt aDataLength )
118 __ASSERT_DEBUG(aRefCodedData,Panic(EBadArgument));
119 __ASSERT_DEBUG(aCodedData,Panic(EBadArgument));
121 for( TInt i = 0; i < aDataLength; i++ )
123 INFO_PRINTF6( _L("delta %u p1 %u p2 %u p1 %x p2 %x"), (*aRefCodedData-*aCodedData),*aRefCodedData, *aCodedData, *aRefCodedData, *aCodedData );
132 * @param aRefCodedData
137 template <class T, class Comparator, TInt A, TInt B, TInt C>
138 void CTestStepCodecUnitTest<T,Comparator, A, B, C>::Print16BitResults( TUint8* aRefCodedData, TUint8* aCodedData, TInt aDataLength )
140 //[precondition pointers are aok]
141 __ASSERT_DEBUG(aRefCodedData,Panic(EBadArgument));
142 __ASSERT_DEBUG(aCodedData,Panic(EBadArgument));
143 //[precondition data is of even length ]
144 __ASSERT_DEBUG( (aDataLength % 2 == 0),Panic(EBadArgument));
146 TInt length = aDataLength /2;
147 TInt16 refCodedValue = 0;
148 TInt16 codedValue = 0;
149 for( TInt i = 0; i < length; i++ )
151 refCodedValue = static_cast<TInt16>( aRefCodedData[0] );
152 refCodedValue |= static_cast<TInt16>((aRefCodedData[1] << 8 ));
153 codedValue = static_cast<TInt16>( aCodedData[0] &KAndMask8bit);
154 codedValue |= static_cast<TInt16>((aCodedData[1] << 8 ));
155 INFO_PRINTF6( _L("delta %d p1 %d p2 %d p1 %x p2 %x"), (refCodedValue-codedValue),refCodedValue, codedValue, refCodedValue, codedValue );
162 * CTestStepCodecUnitTest
165 template <class T, class Comparator, TInt A, TInt B, TInt C>
166 CTestStepCodecUnitTest<T,Comparator, A, B, C>::CTestStepCodecUnitTest( TUint aTestIndex )
168 //[precondition valid index ]
169 // __ASSERT_DEBUG( (aTestIndex >= 0),Panic(EBadArgument)); // EABI warning removal
170 __ASSERT_DEBUG( (aTestIndex < (sizeof(KTestParameters)/sizeof(TCodecUnitTestParams))),Panic(EBadArgument));
171 // store a pointer to the test parameters
172 iTestParameters = &(KTestParameters[aTestIndex]);
173 // store the name of this test case
174 // this is the name that is used by the script file
175 iTestStepName = iTestParameters->iTestName;
180 * ~CTestStepCodecUnitTest
183 template <class T, class Comparator, TInt A, TInt B, TInt C>
184 CTestStepCodecUnitTest<T,Comparator, A, B, C>::~CTestStepCodecUnitTest()
192 template <class T, class Comparator, TInt A, TInt B, TInt C>
193 TVerdict CTestStepCodecUnitTest<T,Comparator, A, B, C>::DoTestStepL()
196 TVerdict result = EPass;
198 // code and decode the input file
199 TInt numBuffersToProcess = ComputeBuffersToProcess();
200 TInt codedBufferSize = numBuffersToProcess*iCodecUnderTest->SinkBufferSize();
201 iCodedData = CMMFDescriptorBuffer::NewL( codedBufferSize);
202 // Compare the results and return test status
203 TUint8* ptrSrc = CONST_CAST(TUint8*,iSourceData->Data().Ptr());
204 TUint8* ptrDest = CONST_CAST(TUint8*,iCodedData->Data().Ptr());
205 CMMFDataBuffer* srcBuffer = CMMFDescriptorBuffer::NewL(iCodecUnderTest->SourceBufferSize());
206 CleanupStack::PushL(srcBuffer);
207 CMMFDataBuffer* destBuffer = CMMFDescriptorBuffer::NewL(iCodecUnderTest->SinkBufferSize());
208 TUint8* pInBuffer = CONST_CAST(TUint8*,srcBuffer->Data().Ptr());
209 TUint8* pOutBuffer = CONST_CAST(TUint8*,destBuffer->Data().Ptr());
210 CleanupStack::PushL(destBuffer);
212 for( TInt i = 0; i < numBuffersToProcess; i++)
214 //[ copy data & increment input pointer]
215 Mem::Copy( pInBuffer, ptrSrc, iCodecUnderTest->SourceBufferSize() );
216 srcBuffer->Data().SetLength( iCodecUnderTest->SourceBufferSize() );
217 ptrSrc+= iCodecUnderTest->SourceBufferSize();
220 iCodecUnderTest->ProcessL( *srcBuffer, *destBuffer);
222 //[ copy out the data & increment pointer ]
223 Mem::Copy( ptrDest, pOutBuffer, iCodecUnderTest->SinkBufferSize() );
224 iCodedData->Data().SetLength( (i+1)*iCodecUnderTest->SinkBufferSize() );
225 destBuffer->Data().SetLength(0); // reset buffer length
226 ptrDest+=iCodecUnderTest->SinkBufferSize();
229 //[ compare the coded data against the reference data]
230 //[ compare the processed number of bytes in the
231 // coded buffer to the reference data]
232 __ASSERT_DEBUG( iRefCodedData->Data().Length() >= iCodedData->Data().Length(),Panic(EBadInvariant));
234 TUint8* ptr1 = CONST_CAST(TUint8*,iRefCodedData->Data().Ptr());
235 TUint8* ptr2 = CONST_CAST(TUint8*,iCodedData->Data().Ptr());
237 if(!iComparator.CompareL( ptr1,ptr2, iCodedData->Data().Length())!=0)
239 INFO_PRINTF1( _L("Comparison has failed"));
240 //(this->*iPrintFormats[ C ])( ptr1, ptr2, iCodedData->Data().Length() );
245 CleanupStack::PopAndDestroy(2,srcBuffer); //srcBuffer, destBuffer
255 * DoTestStepPreambleL
258 template <class T, class Comparator, TInt A, TInt B, TInt C>
259 TVerdict CTestStepCodecUnitTest<T,Comparator,A,B, C>::DoTestStepPreambleL()
261 //[ assert preconditions on a and b ]
262 __ASSERT_DEBUG( A >= 0, Panic(EBadInvariant)); //sanity check on data
263 __ASSERT_DEBUG( B >= 0, Panic(EBadInvariant)); //sanity check on data
264 __ASSERT_DEBUG( C >= 0, Panic(EBadInvariant)); //sanity check on data
265 __ASSERT_DEBUG( A < 2, Panic(EBadInvariant)); //sanity check on data
266 __ASSERT_DEBUG( B < 2, Panic(EBadInvariant)); //sanity check on data
267 __ASSERT_DEBUG( C < 2, Panic(EBadInvariant)); //sanity check on data
269 //[ initialise file reader callbacks ]
270 iReaders[ 0 ] = &CTestStepCodecUnitTest<T,Comparator,A,B,C>::ReadWavFileL;
271 iReaders[ 1 ] = &CTestStepCodecUnitTest<T,Comparator,A,B,C>::ReadAuFileL;
273 //[ initialise print format callbacks ]
274 iPrintFormats[ 0 ] = &CTestStepCodecUnitTest<T,Comparator,A,B,C>::Print8BitResults;
275 iPrintFormats[ 1 ] = &CTestStepCodecUnitTest<T,Comparator,A,B,C>::Print16BitResults;
278 iCodecUnderTest = new(ELeave) T; // a cmmfcodec
280 // [ Parse files into buffers, input & comparison
281 // using the configured file readers ]
282 TBuf<40> testFileName = iTestParameters->iInputFilename;
283 (this->*iReaders[ A ])(iSourceData, testFileName );
284 testFileName = iTestParameters->iComparisonFileName;
285 (this->*iReaders[ B ])(iRefCodedData,testFileName );
290 * DoTestStepPostambleL
293 template <class T, class Comparator, TInt A, TInt B, TInt C>
294 TVerdict CTestStepCodecUnitTest<T,Comparator, A, B, C>::DoTestStepPostambleL(void)
297 delete iCodecUnderTest;
300 delete iRefCodedData;
305 * Reads wav file data into the supplied buffer
309 * This function reads the data portion of a wav file
312 template <class T, class Comparator, TInt A, TInt B, TInt C>
313 void CTestStepCodecUnitTest<T,Comparator, A, B, C>::ReadWavFileL( CMMFDataBuffer* &aBuffer, const TDesC& aFile )
315 // connect to the file server
316 User::LeaveIfError(iFs.Connect());
318 // [open the file and read its data contents into the buffer ]
319 // [the assumption will be the data is stored in wav format only]
320 TFileName fileName = GetSuite()->DefaultPath();
321 fileName.Append(aFile);
324 User::LeaveIfError(file1.Open(iFs, fileName, EFileShareAny | EFileStream | EFileRead));
325 CleanupClosePushL(file1);
327 //[ get the size and position of the data from the wav file ]
328 TInt pos = KFmtChunkSize;
329 User::LeaveIfError(file1.Seek( ESeekStart, pos ));
330 TInt fmtChunkSize = 0;
331 User::LeaveIfError(ReadInt(file1, fmtChunkSize));
332 //[ seek to data chunk size ]
333 pos = KFmtChunkSize+fmtChunkSize+8;
334 User::LeaveIfError(file1.Seek(ESeekStart, pos ));
335 //read data chunk size
336 TInt dataChunkSize = 0;
337 User::LeaveIfError(ReadInt(file1, dataChunkSize));
338 //create buffer large eneough to deal with data size
340 User::LeaveIfError(file1.Size(fileSize));
341 __ASSERT_DEBUG( fileSize > dataChunkSize, Panic(EBadInvariant)); //sanity check on data
342 aBuffer = CMMFDescriptorBuffer::NewL(dataChunkSize);
343 User::LeaveIfError(file1.Read( aBuffer->Data(),dataChunkSize));
344 aBuffer->Data().SetLength(dataChunkSize);
346 CleanupStack::PopAndDestroy(1); //file1
350 * Reads Au file data into the supplied buffer
354 * This function reads the data portion of a wav file
357 template <class T, class Comparator, TInt A, TInt B, TInt C>
358 void CTestStepCodecUnitTest<T,Comparator, A, B, C>::ReadAuFileL( CMMFDataBuffer* &aBuffer, const TDesC& aFile )
360 // connect to the file server
361 User::LeaveIfError(iFs.Connect());
363 // [open the file and read its data contents into the buffer ]
364 TFileName fileName = GetSuite()->DefaultPath();
365 fileName.Append(aFile);
368 User::LeaveIfError(file1.Open(iFs, fileName, EFileShareAny | EFileStream | EFileRead));
369 CleanupClosePushL(file1);
371 TInt magicNumber = 0;
372 User::LeaveIfError(ReadIntB(file1, magicNumber));
373 if( magicNumber != KAuMagic )
375 // have not detected the appropriate header
376 INFO_PRINTF1(_L("Have not detected Au Header ie magic number 0x2e736e64"));
377 User::Leave( KErrCorrupt );
382 User::LeaveIfError(ReadIntB(file1, headerSize));
385 User::LeaveIfError(file1.Size(fileSize));
387 //[ filesize - headersize = datasize ]
388 TInt dataSize = fileSize - headerSize;
390 // [ assert that the datasize >= 0 ]
391 __ASSERT_DEBUG( dataSize >= 0, Panic(EBadInvariant)); //sanity check on data
393 //[Seek to the correct position and read data into Buffer]
394 User::LeaveIfError(file1.Seek(ESeekStart, headerSize ));
395 __ASSERT_DEBUG( fileSize > dataSize, Panic(EBadInvariant)); //sanity check on data
397 //[ read the data into a Buffer ]
398 aBuffer = CMMFDescriptorBuffer::NewL(dataSize);
399 User::LeaveIfError(file1.Read( aBuffer->Data(),dataSize));
400 aBuffer->Data().SetLength(dataSize);
402 CleanupStack::PopAndDestroy(1); //file1
406 * Reads file into buffer
408 * @param aFile the file from which to read the data
409 * @param aValue the returned value
410 * This function reads a 32bit value in a rather inefficient way
412 template <class T, class Comparator, TInt A, TInt B, TInt C>
413 TInt CTestStepCodecUnitTest<T,Comparator, A, B, C>::ReadInt( RFile& aFile, TInt& aValue )
416 TPtr8 theDes( data, 4 );
417 User::LeaveIfError(aFile.Read( theDes, 4));
418 // now assemble the data from the buffer
420 aValue |= data[1] << 8;
421 aValue |= data[2] << 16;
422 aValue |= data[3] << 24;
429 * Reads file into buffer
431 * @param aFile the file from which to read the data
432 * @param aValue the returned value
433 * This function reads a 32bit value in BigEndian forma
434 and coverts it to Little Endian in a rather inefficient way
436 template <class T, class Comparator, TInt A, TInt B, TInt C>
437 TInt CTestStepCodecUnitTest<T,Comparator, A, B, C>::ReadIntB( RFile& aFile, TInt& aValue )
440 TPtr8 theDes( data, 4 );
441 User::LeaveIfError(aFile.Read( theDes, 4));
442 // now assemble the data from the buffer
444 aValue |= data[2] << 8;
445 aValue |= data[1] << 16;
446 aValue |= data[0] << 24;
453 * ComputeBuffersToProcess
454 * @precondition InputBuffer has been setup
455 * @precondition Codec has been instantiated
458 template <class T, class Comparator, TInt A, TInt B, TInt C>
459 TInt CTestStepCodecUnitTest<T,Comparator, A, B, C>::ComputeBuffersToProcess()
461 TInt numWholeBuffers = (iSourceData->Data().MaxLength()/iCodecUnderTest->SourceBufferSize() );
462 return numWholeBuffers;
468 * This is used for template instantiation.
472 template class CTestStepCodecUnitTest<CMMFPcm16SwapEndianCodec,TComparator,0,1,1>;
473 template class CTestStepCodecUnitTest<CMMFPcm16ToImaAdpcmCodec,TComparator>;
474 template class CTestStepCodecUnitTest<CMMFImaAdpcmToPcm16Codec,TDbComparator<>,0,0,1>;
475 template class CTestStepCodecUnitTest<CMMFPcm16ToPcmU8Codec,TComparator>;
476 template class CTestStepCodecUnitTest<CMMFPcmU8ToPcm16Codec,TDbComparator<>,0,0,1>;
488 TBool TComparator::CompareL( TUint8* aData, TUint8* aData2, TInt aLength )
490 TBool result = ETrue;
492 User::Leave(KErrArgument);
494 User::Leave(KErrArgument);
496 if( Mem::Compare( aData,aLength, aData2, aLength )!=0)
514 TBool TDbComparator<T>::CompareL( TUint8* aData, TUint8* aData2, TInt aLength )
516 TBool result = ETrue;
518 User::Leave(KErrArgument);
520 User::Leave(KErrArgument);
522 //[ lets compute the signal to noise ratio ]
523 TReal sumSigSquared = 0.0;
524 TReal sumErrorSquared = 0.0;
525 TUint8* pData = aData;
526 TUint8* pData2 = aData2;
527 TInt numSamples = aLength/2;
528 // compute the sum of sig and error squared
529 for( TInt count = 0; count < numSamples; count++ )
531 TInt16 sample1 = static_cast<TInt16>( pData[0] &KAndMask8bit);
532 sample1 |= static_cast<TInt16>((pData[1] << 8 ));
533 TInt16 sample2 = static_cast<TInt16>( pData2[0] &KAndMask8bit);
534 sample2 |= static_cast<TInt16>((pData2[1] << 8 ));
537 sumSigSquared += sample1*sample1;
538 sumErrorSquared += (sample1-sample2)*(sample1-sample2);
542 const TReal tolerance = 0.001;
543 //[precondition error is >= tolerance ]
544 if( sumErrorSquared < tolerance )
545 User::Leave( KErrArgument );
546 //[claculate ratio safely ]
547 Math::Log( sn, (sumSigSquared/sumErrorSquared));
549 TReal threshold = T; // integer used as real with 100ths db accuracy