mmlibs/mmfw/tsrc/mmfunittest/aclnt/TSU_MMF_ACLNT_01/TestStepRecorderCrop.cpp
changeset 0 b8ed18f6c07b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/tsrc/mmfunittest/aclnt/TSU_MMF_ACLNT_01/TestStepRecorderCrop.cpp	Thu Oct 07 22:34:12 2010 +0100
@@ -0,0 +1,791 @@
+// Copyright (c) 2002-2009 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:
+// This file contains an example Test step implementation 
+// This demonstrates the various functions provided
+// by the CTestStep base class which are available within
+// a test step 
+// 
+//
+
+// EPOC includes
+#include <e32base.h>
+#include <e32test.h>
+#include <e32keys.h>
+#include <c32comm.h>
+#include <f32file.h>
+#include <etel.h>
+#include <etelmm.h>
+#include <testframework.h>
+
+//#include <MdaAudioSamplePlayer.h>
+#include <mdaaudiosampleeditor.h>
+//#include <MdaAudioTonePlayer.h>
+
+// Test system includes
+#include <testframework.h>
+
+// Specific includes for this test suite
+#include "TestStepUnitMMFAudClient.h"
+#include "TestSuiteUnitMMFAudClient.h"
+
+// Specific includes for these test steps
+#include "TestStepRecorder.h"
+
+
+#include "MmfAudioController.h"
+#include "mmfclientaudiorecorder.h"
+//#include "MmfClientAudioPlayer.h"
+//#include <mmffourcc.h>
+//#include <mmfpaniccodes.h>
+//#include <mmfFormatImplementationUIDs.hrh>
+// --------------------------------------------
+
+//const TInt KPcm16FrameInterval = 371512;	// EABI warning removal
+
+// frame size is now variable, depeding on the sample rate
+//const TInt KFrameSize8K16Bit = 4096;	// frame size for 8Khz	// EABI warning removal
+
+//if frame size is 4096 bytes, then a sample file of 8KHz, 16bit, mono, 
+// would be 16000 bytes per second, therefore a frame would represent 256 millisecs
+// we make sure the deviation is not greater than a frame since we can only crop frames.
+const TInt KExpectedDeviation	 = (256000); //200000
+
+
+
+
+// Orig duration = 1000120 Us, 90% = 900108 Us; @8KHz, 16bits, 1 channel = 14400 bytes (aligned to sample)
+const TInt KExpectedCropSize1	 = 14400 + 44;
+
+// Second crop - original duration is still taken from source (known error) = 10000120 Us.
+//Therefore crop point = 40% of 10000120 Us = 400048 Us.
+//Crop from begining to 400048Us with @8KHz, 16bits, 1 channel = 6400 bytes (aligned to sample).
+//New file = KExpectedCropSize1 - 6400 = 8046
+const TInt KExpectedCropSize2	 = 8000 + 44;
+
+
+
+/**
+ *
+ * Static constructor for CTestStepRecorderCrop.
+ *
+ *
+ * @return	"CTestStepRecorderCrop*"
+ *			The constructed CTestStepRecorderCrop
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecorderCrop* CTestStepRecorderCrop::NewL(const TDesC& aTestName, TBool aIsConverterTest)
+	{
+	CTestStepRecorderCrop* self = new(ELeave) CTestStepRecorderCrop(aTestName, aIsConverterTest);
+	return self;
+	}
+
+/**
+ *
+ * Test step constructor.
+ * Each test step initialises its own name.
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecorderCrop::CTestStepRecorderCrop(const TDesC& aTestName, TBool aIsConverterTest)
+: iError(0), iHasCropped(EFalse), iIsConverterTest(aIsConverterTest)
+	{
+	// store the name of this test case
+	// this is the name that is used by the script file
+	iTestStepName = aTestName;
+	}
+
+/**
+ *
+ * Test step destructor.
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecorderCrop::~CTestStepRecorderCrop()
+	{
+	}
+
+/**
+ *
+ * Test step Preamble.
+ *
+ * @xxxx
+ * 
+ */
+enum TVerdict CTestStepRecorderCrop::DoTestStepPreambleL(void)
+	{
+	 enum TVerdict verdict = EPass;
+	 // this installs the scheduler
+	 verdict = CTestStepUnitMMFAudClient::DoTestStepPreambleL();
+
+	// Printing to the console and log file
+	INFO_PRINTF1(iTestStepName);
+	if (!iIsConverterTest)
+		INFO_PRINTF1(_L("this is a test of CMdaAudioRecorderUtility::CropL(beginning/end)"));
+	else
+		INFO_PRINTF1(_L("this is a test of CMdaAudioConvertUtility::CropL(beginning/end)"));
+
+	// open the file to be cropped
+	
+	
+	User::LeaveIfError(iFs.Connect());
+	iFileMan = CFileMan::NewL(iFs);
+	if (iIsConverterTest)
+		{
+		if(!GetStringFromConfig(_L("SectionOne"), _L("AudioFNameToConvertAndCrop"), iFileName))  //au
+			return EInconclusive;
+
+		iFileNameTmp = iFileName;
+		_LIT(KExtTmp,".tmp.au");
+		iFileNameTmp.Append(KExtTmp);
+
+		//create a copy of the input file to work on
+		User::LeaveIfError(iFileMan->Copy(iFileName, iFileNameTmp));
+
+		//construct an autput filename
+		iOutputFileName = iFileName;
+		_LIT(KExtOutput,".output.wav");
+		iOutputFileName.Append(KExtOutput);
+
+		//delete any existing output file
+		TInt deleteErr = iFileMan->Delete(iOutputFileName); //delete oput file before start test
+		if(deleteErr != KErrNone && deleteErr != KErrNotFound)
+			User::Leave(deleteErr);	
+		}
+	else
+		{
+		if(!GetStringFromConfig(_L("SectionOne"), _L("AudioFNameToCrop"), iFileName))
+			return EInconclusive;
+
+		iFileNameTmp = iFileName;
+		_LIT(KExtTmp,".tmp.wav");
+		iFileNameTmp.Append(KExtTmp);
+
+		User::LeaveIfError(iFileMan->Copy(iFileName, iFileNameTmp));
+		}
+
+
+	iFs.Close();
+	delete iFileMan;
+	iFileMan = NULL;
+	User::After(200000); // just in case
+
+	if (!iIsConverterTest)
+		{//0240
+		if ( (iRecorder = CMMFMdaAudioRecorderUtility::NewL(*this)) == NULL )
+			verdict = EInconclusive;
+
+		iRecorder->OpenFileL(iFileNameTmp);
+		CActiveScheduler::Start(); 
+		if (iError != KErrNone ||
+			iRecorder->State() != CMdaAudioRecorderUtility::EOpen)
+			return EInconclusive;
+
+		iRecorder->SetGain(iRecorder->MaxGain()/2);
+		iOrigDuration = iRecorder->Duration().Int64();
+		
+		if ( iError != KErrNone || 
+			iRecorder->State() != CMdaAudioRecorderUtility::EOpen)
+			verdict = EInconclusive;
+		}
+	else
+		{//566
+		if ( (iConvert = CMdaAudioConvertUtility::NewL(*this)) == NULL )
+			verdict = EInconclusive;
+
+		iConvert->OpenL(iFileNameTmp, iOutputFileName);
+		// Another initialisation of the convert utility
+		// should behave the same as the one above
+		//TMdaFileClipLocation* target = new TMdaFileClipLocation(iFileName3);
+		//TMdaAuClipFormat auClipFormat;
+		//TMdaPcm16BitAuCodec au16bitCodec; //KMMFFourCCCodePCM16B
+		//iConvert->OpenL(iFileNameTmp, target, 
+		//				&auClipFormat,
+		//				&au16bitCodec);
+
+		CActiveScheduler::Start(); 
+		if (iError != KErrNone ||
+			iConvert->State() != CMdaAudioConvertUtility::EOpen)
+			return EInconclusive;
+
+		iOrigDuration = iConvert->Duration().Int64();
+		
+		if ( iError != KErrNone || 
+			iConvert->State() != CMdaAudioConvertUtility::EOpen)
+			verdict = EInconclusive;
+
+		// convert because cropping only applies to destination
+		// before conversion destination is empty -> hence no cropping available
+		TRAPD(err, iConvert->ConvertL());
+		// Note: Converting by just openning a wav and an au file will work incorrectly:
+		// the resutling file will contain noise, since the default conversion will be e.g.
+		// wav:PCM16 -> au:PCM16, instead of wav:PCM16 -> au:PCM16BE (Big Endian)
+		// Cropping, duration, position and the flow of the tested code is fine though, 
+		// so it serves the purpose of this test, i.e. cropping
+		// This error might be fixed in the future so Big Endian codec is chosen
+		CActiveScheduler::Start(); // open -> record
+		if (err != KErrNone || iError != KErrNone)
+			return EInconclusive;
+		CActiveScheduler::Start(); // record -> open
+		if (err != KErrNone || iError != KErrNone)
+			return EInconclusive;
+		}
+
+
+	return verdict;
+	}
+
+/**
+ *
+ * Test step Postamble.
+ *
+ * @xxxx
+ * 
+ */
+enum TVerdict CTestStepRecorderCrop::DoTestStepPostambleL(void)
+	{
+	if (!iIsConverterTest)
+		iRecorder->Close();
+	else
+		iConvert->Close();
+
+	//delete the temp, cropped file 
+	User::LeaveIfError(iFs.Connect());
+	iFileMan = CFileMan::NewL(iFs);
+	User::LeaveIfError(iFileMan->Delete(iFileNameTmp));
+
+	if (iIsConverterTest)
+		User::LeaveIfError(iFileMan->Delete(iOutputFileName));
+
+	iFs.Close();
+	delete iFileMan;
+	iFileMan = NULL;
+
+	if (!iIsConverterTest)
+		{//240
+		delete iRecorder;
+		iRecorder = NULL;
+		}
+	else
+		{//566
+		delete iConvert;
+		iConvert = NULL;
+		}
+	
+	//[ Destroy the scheduler ]
+	return CTestStepUnitMMFAudClient::DoTestStepPostambleL();
+	}
+
+/**
+ *
+ * Callback Handle.
+ *
+ * @xxxx
+ * 
+ */
+void CTestStepRecorderCrop::MoscoStateChangeEvent(CBase* /*aObject*/,
+														  TInt /*aPreviousState*/,
+														  TInt /*aCurrentState*/,
+														  TInt aErrorcCode)
+	{
+	iError = aErrorcCode;
+	CActiveScheduler::Stop();
+	}
+
+void CTestStepRecorderCrop::CropAndStartSchedulerL(const TTimeIntervalMicroSeconds& aBegin,
+												   const TTimeIntervalMicroSeconds& aEnd) 
+	{
+	if (!iIsConverterTest)
+		{
+		iRecorder->CropL(aBegin, aEnd);
+		//CActiveScheduler::Start(); // it works synchronously even if we don't start the ActiveScheduler
+
+
+		//Check if the cropped duration is within the deviation from the expected duration
+		TInt64 cropDur = iRecorder->Duration().Int64();
+		TInt64 difDur = aEnd.Int64() - aBegin.Int64();
+		TInt delta = I64INT(cropDur - difDur);
+		if(delta < 0)
+			delta *= (-1);
+		
+		if ( delta <= KExpectedDeviation )
+			iHasCropped = ETrue;
+		//iRecorder->Stop();
+		}
+	else // not really used in this test
+		{
+		}
+	}
+	
+void CTestStepRecorderCrop::CropAndStartSchedulerL(TTimeIntervalMicroSeconds aCropPoint, TBool aCropToEnd) 
+	{
+	_LIT(_toEnd,"to end from");
+	_LIT(_fromBegining,"from beginning to");
+
+	if (!iIsConverterTest)
+		{//240
+		iRecorder->SetPosition(aCropPoint);
+		const TTimeIntervalMicroSeconds pos = iRecorder->Position();
+
+		iRecorder->CropL(aCropToEnd);
+		//CActiveScheduler::Start(); // it works synchronously even if we don't start the ActiveScheduler
+
+
+		//Check if the cropped duration is within the deviation from the expected duration
+		TInt64 cropDur = iRecorder->Duration().Int64();
+		TInt64 difDur = 0;
+		if (aCropToEnd)
+			difDur = pos.Int64();
+		else
+			difDur = iOrigDuration - pos.Int64();
+		TInt delta = I64INT(cropDur - difDur);
+		if(delta < 0)
+			delta *= (-1);
+		
+		if ( delta <= KExpectedDeviation )
+			iHasCropped = ETrue;
+		
+		
+		INFO_PRINTF2(_L("Cropping from original duration = %d"), iOrigDuration);
+		INFO_PRINTF3(_L("Cropping %S %d "), (aCropToEnd ? &_toEnd : &_fromBegining), aCropPoint.Int64());
+		INFO_PRINTF2(_L("Crop point was set at = %d"), pos.Int64());
+		INFO_PRINTF2(_L("Cropped to = %d"), cropDur);
+		//iRecorder->Stop();
+		}
+	else
+		{
+		iHasCropped = ETrue;
+
+		iConvert->SetPosition(aCropPoint);
+
+		if (aCropToEnd)
+			iConvert->CropL(); // default: crop to end
+		else
+			iConvert->CropFromBeginningL();
+		//CActiveScheduler::Start(); // it works synchronously even if we don't start the ActiveScheduler
+
+
+		//Check if the cropped duration is within the deviation from the expected duration
+		// Note: there is a problem with duration, since Duration() always returns the 
+		// duration of the original clip (source clip) before conversion
+		// One can set the position beyond the end of the cropped file, but still below the
+		// original duration before cropping, and start a second cropping. This might lead
+		// to unexpected behaviour.
+		//TInt64 cropDur = iConvert->Duration().Int64();
+		// there is no converter API to check the destination(sink) duration after cropping
+
+		// we are just checking if the cropping took place by checking the size of the
+		// cropped file
+		TInt croppedSize = 0;
+
+		User::LeaveIfError(iFs.Connect());
+		RFile croppedFile;
+		User::LeaveIfError(croppedFile.Open(iFs, iOutputFileName, EFileRead ));
+		CleanupClosePushL(croppedFile);
+		User::LeaveIfError(croppedFile.Size(croppedSize));
+
+		TInt expectedCrop=0;
+
+		if (aCropToEnd)
+			{
+			expectedCrop=KExpectedCropSize1;
+			if (croppedSize != expectedCrop)
+			iHasCropped = EFalse;
+			}
+		else // second crop to beginning
+			{
+			expectedCrop=KExpectedCropSize2;
+			if (croppedSize != expectedCrop) 
+				iHasCropped = EFalse;
+			}
+
+		INFO_PRINTF2(_L("Cropping from original duration = %d"), iOrigDuration);
+		INFO_PRINTF3(_L("Cropping %S %d "), (aCropToEnd ? &_toEnd : &_fromBegining), aCropPoint.Int64());
+		INFO_PRINTF3(_L("Cropped to = %d bytes (expected %d bytes)"), croppedSize,expectedCrop);
+
+		CleanupStack::PopAndDestroy(&croppedFile);
+		iFs.Close();
+		}
+	}
+
+
+	
+/**
+ *
+ * Do the test step.
+ * Each test step must supply an implementation for DoTestStepL.
+ *
+ * @return	"TVerdict"
+ *			The result of the test step
+ *
+ * @xxxx
+ * 
+ */
+TVerdict CTestStepRecorderCrop::DoTestStepL()
+	{
+	iTestStepResult = EPass;
+    TInt err       = KErrNone;
+
+	//NB: crop points are carfully choosen to ensure that at least one block is removed 
+	//during each crop operation.
+
+	if (!iIsConverterTest)
+		{//240
+		//crop 40% from beginning of clip
+		TRAP( err, CropAndStartSchedulerL(iOrigDuration / 5 *2, EFalse) );
+
+		if (err != KErrNone ||
+			!iHasCropped ||
+			iRecorder->State() != CMdaAudioRecorderUtility::EOpen )
+			return EFail;
+
+		iHasCropped = EFalse;
+		iOrigDuration = iRecorder->Duration().Int64();
+		//crop frop 80% to end of file
+		TRAP( err, CropAndStartSchedulerL(iOrigDuration - (iOrigDuration/5), ETrue) );
+
+		if (err != KErrNone ||
+			!iHasCropped ||
+			iRecorder->State() != CMdaAudioRecorderUtility::EOpen )
+			{
+			INFO_PRINTF4(_L("Failed err=%d  iHasCropped=%d  State=%d"),err, iHasCropped,  iRecorder->State());
+			return EFail;
+			}
+		}
+	else // iIsConverterTest == ETRue
+		{//566
+		//crop from 90% to end of file
+		TRAP( err, CropAndStartSchedulerL(iOrigDuration - (iOrigDuration/10), ETrue) );
+
+		if (err != KErrNone ||
+			!iHasCropped ||
+			iConvert->State() != CMdaAudioConvertUtility::EOpen )
+			{
+			INFO_PRINTF4(_L("Failed err=%d  iHasCropped=%d  State=%d"),err, iHasCropped,  iConvert->State());
+			return EFail;
+			}
+
+		// crop again
+		iHasCropped = EFalse;
+		iOrigDuration = iConvert->Duration().Int64();
+		
+		//crop 40% from beginning of clip
+		TRAP( err, CropAndStartSchedulerL(iOrigDuration / 5 * 2, EFalse) ); // crop from beginning
+
+		if (err != KErrNone ||
+			!iHasCropped ||
+			iConvert->State() != CMdaAudioConvertUtility::EOpen )
+			{
+			INFO_PRINTF4(_L("Failed err=%d  iHasCropped=%d  State=%d"),err, iHasCropped,  iConvert->State());
+			return EFail;
+			}
+		}
+	
+	INFO_PRINTF1(_L("finished with this test step"));
+	// test steps return a result
+	return iTestStepResult;
+	}
+
+//
+// add new test here for descriptor crop
+//
+
+/**
+ *
+ * Static constructor for CTestStepRecCropDescriptor
+ *
+ *
+ * @return	"CTestStepRecCropDescriptor*"
+ *			The constructed CTestStepRecCropDescriptor
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecCropDescriptor* CTestStepRecCropDescriptor::NewL(const TDesC& aTestName, 	TBool aUseOldApi )
+	{
+	CTestStepRecCropDescriptor* self = new(ELeave) CTestStepRecCropDescriptor(aTestName, aUseOldApi);
+	return self;
+	}
+
+/**
+ *
+ * Test step constructor.
+ * Each test step initialises its own name.
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecCropDescriptor::CTestStepRecCropDescriptor(const TDesC& aTestName, 	TBool aUseOldApi ) 
+: iError(0), iHasCropped(EFalse), iIsOldAPiTest( aUseOldApi )
+	{
+	// store the name of this test case
+	// this is the name that is used by the script file
+	iTestStepName = aTestName;
+	}
+
+/**
+ *
+ * Test step destructor.
+ *
+ * @xxxx
+ * 
+ */
+CTestStepRecCropDescriptor::~CTestStepRecCropDescriptor()
+	{
+	}
+
+/**
+ *
+ * Test step Preamble.
+ *
+ * @xxxx
+ * 
+ */
+enum TVerdict CTestStepRecCropDescriptor::DoTestStepPreambleL(void)
+	{
+	 enum TVerdict verdict = EPass;
+	 // this installs the scheduler
+	 verdict = CTestStepUnitMMFAudClient::DoTestStepPreambleL();
+
+	// Printing to the console and log file
+	INFO_PRINTF1(iTestStepName);
+
+	INFO_PRINTF1(_L("this is a test of CMdaAudioRecorderUtility::CropL(beginning/end)"));
+	
+	// open the file to be cropped
+
+	if(!(GetStringFromConfig(_L("SectionOne"), _L("AudioFNameToCrop"), iFileName)))
+		{
+		return EInconclusive;
+		}
+	
+	// copy file to descriptor
+	iFileNameTmp = iFileName;
+
+	//[ append to file name and copy file to tmp file ]
+	_LIT(KExtTmp,".tmp.wav");
+	iFileNameTmp.Append(KExtTmp);
+
+    iFs.Connect();
+	iFileMan = CFileMan::NewL(iFs);
+	iFileMan->Copy(iFileName, iFileNameTmp);
+	iFs.Close();
+	delete iFileMan;
+	iFileMan = NULL;
+
+
+	//[ read the file into a descriptor ]
+	ReadFileToDescriptorL( iFileNameTmp);
+	
+	delete iFileMan;
+	iFileMan = NULL;
+
+	User::After(200000); // just in case
+	
+	if ( (iRecorder = CMMFMdaAudioRecorderUtility::NewL(*this)) == NULL )
+		verdict = EInconclusive;
+	
+	//[ Open the descriptor]
+    //[ set up the tdes8 here and every thing should be kosher]
+
+	if( iIsOldAPiTest ) 
+		{
+		iRecorder->OpenDesL( *iDes8 );
+		}
+	else 
+		{
+		//[ since TDes8 is derived from TDesC8 we can do this cast
+		// to force the correct api to be used ]
+		iRecorder->OpenDesL( (const TDesC8&)(*iDes8)  );
+		}
+
+
+	CActiveScheduler::Start(); 
+	if (iError != KErrNone ||
+		iRecorder->State() != CMdaAudioRecorderUtility::EOpen)
+		return EInconclusive;
+	
+	iRecorder->SetGain(iRecorder->MaxGain()/2);
+	iOrigDuration = iRecorder->Duration().Int64();
+	
+	if ( iError != KErrNone || 
+		iRecorder->State() != CMdaAudioRecorderUtility::EOpen)
+		verdict = EInconclusive;
+
+	return verdict;
+	}
+
+/**
+ *
+ * Test step Postamble.
+ *
+ * @xxxx
+ * 
+ */
+enum TVerdict CTestStepRecCropDescriptor::DoTestStepPostambleL(void)
+	{
+	iRecorder->Close();
+
+	//delete the temp, cropped file 
+	iFs.Connect();
+	iFileMan = CFileMan::NewL(iFs);
+	iFileMan->Delete(iFileNameTmp);
+
+	iFs.Close();
+	delete iFileMan;
+	iFileMan = NULL;
+
+	delete iRecorder;
+	iRecorder = NULL;
+
+	delete iDescHBuf;
+	delete iDes8;
+		
+	//[ Destroy the scheduler ]
+	return CTestStepUnitMMFAudClient::DoTestStepPostambleL();
+	}
+
+/**
+ *
+ * Callback Handle.
+ *
+ * @xxxx
+ * 
+ */
+void CTestStepRecCropDescriptor::MoscoStateChangeEvent(CBase* /*aObject*/,
+														  TInt /*aPreviousState*/,
+														  TInt /*aCurrentState*/,
+														  TInt aErrorcCode)
+	{
+	iError = aErrorcCode;
+	CActiveScheduler::Stop();
+	}
+
+void CTestStepRecCropDescriptor::CropAndStartSchedulerL(const TTimeIntervalMicroSeconds& aBegin,
+												   const TTimeIntervalMicroSeconds& aEnd) 
+	{
+		iRecorder->CropL(aBegin, aEnd);
+	
+		//Check if the cropped duration is within the deviation from the expected duration
+		TInt64 cropDur = iRecorder->Duration().Int64();
+		TInt64 difDur = aEnd.Int64() - aBegin.Int64();
+		TInt delta = I64INT(cropDur - difDur);
+		if(delta < 0)
+			delta *= (-1);
+		
+		if ( delta <= KExpectedDeviation )
+			iHasCropped = ETrue;
+
+	}
+	
+void CTestStepRecCropDescriptor::CropAndStartSchedulerL(TBool aCropToEnd) 
+	{
+	const TTimeIntervalMicroSeconds pos = iRecorder->Position();
+	
+	iRecorder->CropL(aCropToEnd);
+	
+	//Check if the cropped duration is within the deviation from the expected duration
+	TInt64 cropDur = iRecorder->Duration().Int64();
+	TInt64 difDur = 0;
+	if (aCropToEnd)
+		difDur = pos.Int64();
+	else
+		difDur = iOrigDuration - pos.Int64();
+	TInt delta = I64INT(cropDur - difDur);
+	if(delta < 0)
+		delta *= (-1);
+	
+	if ( delta <= KExpectedDeviation )
+		iHasCropped = ETrue;
+
+	}
+	
+/**
+ *
+ * Do the test step.
+ * Each test step must supply an implementation for DoTestStepL.
+ *
+ * @return	"TVerdict"
+ *			The result of the test step
+ *
+ * @xxxx
+ * 
+ */
+TVerdict CTestStepRecCropDescriptor::DoTestStepL()
+	{
+	iTestStepResult = EPass;
+    TInt err       = KErrNone;
+
+	const TTimeIntervalMicroSeconds middle( iOrigDuration / 2 );
+	const TTimeIntervalMicroSeconds threeQuarters( iOrigDuration - (iOrigDuration/4) );
+
+    iRecorder->SetPosition(threeQuarters);
+	TRAP( err, CropAndStartSchedulerL(ETrue) );
+	
+	if (err != KErrNone ||
+		!iHasCropped ||
+		iRecorder->State() != CMdaAudioRecorderUtility::EOpen )
+		return EFail;
+	
+	iHasCropped = EFalse;
+	iOrigDuration = iRecorder->Duration().Int64();
+	iRecorder->SetPosition(middle);
+	
+	CropAndStartSchedulerL(EFalse);
+	
+	if (err != KErrNone ||
+		!iHasCropped ||
+		iRecorder->State() != CMdaAudioRecorderUtility::EOpen )
+		return EFail;
+		
+	INFO_PRINTF1(_L("finished with this test step"));
+
+	return iTestStepResult;
+	}
+
+/**
+ * This function reads from a source file into the member variable heap buffer, 'iDescHBuf'.
+ * @param aFilename - The file to read from.
+ */
+void CTestStepRecCropDescriptor::ReadFileToDescriptorL(const TDesC& aFilename )
+	{	
+	RFs rfs;
+	rfs.Connect();
+	RFile file;
+
+	// Try to open the file.
+	User::LeaveIfError( file.Open(rfs,aFilename,EFileRead|EFileShareAny) );
+
+	// Create the databuffer in which to store the data.
+	TInt fileSize = 0;
+	file.Size(fileSize);
+	iDescHBuf = HBufC8::NewL(fileSize);	
+	
+	TPtr8 dataBuf = iDescHBuf->Des();	
+
+	// Read the data from the file to the data buffer
+	User::LeaveIfError( file.Read(dataBuf) );	
+
+	//[ set up the descriptor ]
+	iDes8 = new (ELeave) TPtr8( NULL, 0 );
+	iDes8->Set( iDescHBuf->Des());
+    
+	file.Close();
+	rfs.Close();	
+	}
+
+