mmfenh/advancedaudiocontroller/tsrc/advancedaudiocontrollertestmodule/AudioRecorderTestModule/src/RecordingBase.cpp
/*
* Copyright (c) 2007 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: AudioRecorder Test
*
*/
#include "RecordingBase.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRecordingBase::CRecordingBase(CTestModuleIf *aConsole, CStifLogger *aLogger)
{
console = aConsole;
logger = aLogger;
timeToRecord = 0;
maxFileSize = 0;
relativeGain = 0; //for Gain
callbackErr = KErrNone; //for Gain
expectedBalance = -999; // for balance
expectedBitRate = 0;
expectedSampleRate = 0;
fileDuration = 0;
existingDuration = 0;
CropTest = false;
isWav = false;
isMp4 = false;
isAmr = false;
}
CRecordingBase::~CRecordingBase()
{
TInt err( iFileMan->Delete( recordingFileName ) );
if (recorder) delete recorder;
iFs.Close();
if(iFileMan) delete iFileMan;
recorder = NULL;
}
CRecordingBase* CRecordingBase::CreateObjectL(CTestModuleIf *aConsole, CStifLogger *aLogger)
{
//aLogger->Log(_L("CRecordingBase::CreateObjectL"));
return (new (ELeave) CRecordingBase(aConsole, aLogger));
}
CRecordingBase* CRecordingBase::NewL(CTestModuleIf *aConsole,
CStifLogger *aLogger,
TFileName *fileName,
CreateObjectFunction coFunc)
{
CRecordingBase* self;
if (coFunc == NULL)
self = CreateObjectL(aConsole,aLogger);
else
self = coFunc(aConsole,aLogger);
CleanupStack::PushL(self);
TRAPD(err, self->ConstructL(fileName));
if (err != KErrNone)
{
CleanupStack::PopAndDestroy();
return NULL;
}
CleanupStack::Pop(self);
return self;
}
TInt CRecordingBase::RunTestL(CTestModuleIf *aConsole,
CStifLogger *aLogger,
CStifSectionParser *aParser,
TInt* clipCounter,
CreateObjectFunction coFunc)
{
TInt error = KErrNone;
//Create scheduler
aLogger->Log(_L("Creating scheduler"));
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(scheduler); // push to clean-up stack
CActiveScheduler::Install(scheduler); // install as active scheduler
CRecordingBase* recorderObj;
// create recorder,
if ((error = CRecordingBase::CreateRecorderL(aConsole, aLogger, aParser, clipCounter, coFunc, recorderObj)) != KErrNone)
{
CleanupStack::PopAndDestroy(); //scheduler
return error;
}
CleanupStack::PushL(recorderObj);
//SimpleRecording will read Error range
error = CRecordingBase::SimpleRecordL(aConsole, aLogger, recorderObj, true, aParser);
CleanupStack::PopAndDestroy(2); // recorderObj, scheduler
return error;
}
void CRecordingBase::ConstructL(TFileName* fileName)
{
logger->Log(_L("Creating file: %S"),fileName);
User::LeaveIfError( iFs.Connect() );
iFileMan = CFileMan::NewL( iFs );
recorder = CMdaAudioRecorderUtility::NewL(*this);
if (recorder)
{
TRAPD(err,recorder->OpenFileL(*fileName));
if (err != KErrNone)
{
logger->Log(_L("Error %d opening file: %S"),err,fileName);
User::Leave(KErrRecOpenFile);
}
}
}
void CRecordingBase::MoscoStateChangeEvent(CBase* /*aObject*/,
TInt aPreviousState,
TInt aCurrentState,
TInt aErrorCode)
{
TInt err = KErrNone;
#ifdef _DEBUG
RDebug::Print (_L ("CRecordingBase::MoscoStateChangeEvent"));
#endif
logger->Log(_L("MoscoStateChangeEvent called, error: %d prev: %d curr : %d"),
aErrorCode,aPreviousState,aCurrentState);
/*
TTime time;
time.UniversalTime();
logger->Log(_L("MoscoStateChangeEvent time High: %u, Low: %u"),time.Int64().High(),time.Int64().Low());
*/
callbackErr = aErrorCode; // for Gain
if (recorder && aErrorCode == KErrNone && aCurrentState == CMdaAudioClipUtility::EOpen &&
aPreviousState == 0)
{
// recorder->SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal);
// recorder->SetGain(recorder->MaxGain());
// TInt64 duration = recorder->Duration().Int64();
existingDuration = recorder->Duration().Int64();
if (existingDuration)
{
logger->Log(_L("File Already Exist with duration = %d"), existingDuration);
logger->Log(_L("Save the existingDuration"));
//recorder->SetPosition(TTimeIntervalMicroSeconds(TInt64(0)));
//TRAP(err,recorder->CropL());
}
if (err != KErrNone)
logger->Log(_L("Error cropping file: %d"),err);
if (maxFileSize != 0)
{
recorder->SetMaxWriteLength(maxFileSize);
logger->Log(_L("Set maxWriteLength: %d"), maxFileSize);
}
if (!isAmr && isBitRateTest)
{
logger->Log(_L("Not AMR format, Stop now."));
CActiveScheduler::Stop();
}
else
{
logger->Log(_L("StartRecording"));
StartRecordingL();
}
}
if (recorder && aPreviousState == CMdaAudioClipUtility::ERecording)
{
logger->Log(_L("Recorder stopping"));
recorder->Stop();
CActiveScheduler::Stop();
}
else
{
if (recorder && aErrorCode != KErrNone)
{
//logger->Log(_L("Reaching maximum file size. Recorder stopping"));
logger->Log(_L("unexpected results, error: %d"), aErrorCode);
recorder->Stop();
CActiveScheduler::Stop();
}
}
}
TInt CRecordingBase::ExecuteL(CParameters* /*aParams*/)
{
if (recorder)
{
logger->Log(_L("RecordClip recorder stopping"));
recorder->Stop();
if (CropTest)
{
fileDuration = recorder->Duration();
position = fileDuration.Int64()*relativePos/100.0;
recorder->SetPosition(TTimeIntervalMicroSeconds(position));
logger->Log(_L("The audio file duration: %d"), fileDuration);
logger->Log(_L("Crop position: %d"),position);
if (fromBeging)
{
logger->Log(_L("It starts to call CropL()"));
TRAPD(error,recorder->CropL());
}
else
{
logger->Log(_L("It starts to call CropFromBeginningL()"));
TRAPD(error, recorder->CropFromBeginningL());
}
newFileDuration = recorder->Duration();
}
CActiveScheduler::Stop();
}
return 0;
}
TInt CRecordingBase::StartRecordingL()
{
TInt err(KErrNone);
int i;
if (recorder)
{
if (isMp4)
{
logger->Log(_L("Record a mp4 audio file, set SampleRate, Channel and BitRate"));
//Set SampleRate
RArray<TUint> supportedSampleRates;
TRAP(err, recorder->GetSupportedSampleRatesL(supportedSampleRates) );
if (err != KErrNone)
{
logger->Log(_L("Error %d for GetSupportedSampleRateL"),err );
return err;
}
for (i=0; i<supportedSampleRates.Count(); i++)
{
if (expectedSampleRate == supportedSampleRates[i])
{
TRAP(err, recorder->SetDestinationSampleRateL(expectedSampleRate));
if (err)
{
logger->Log(_L("Error %d for SetDestinationSampleRateL %d"),err, expectedSampleRate );
return err;
}
break;
}
}
if (i>= supportedSampleRates.Count())
{
logger->Log(_L("expectedSampleRate %d is not supported by system, invalid test case."), expectedSampleRate );
callbackErr = KErrInvalidId;
return callbackErr;
}
//Set Channel
RArray<TUint> supportedChannels;
TRAP(err, recorder->GetSupportedNumberOfChannelsL(supportedChannels) );
if (err != KErrNone)
{
logger->Log(_L("Error %d for GetSupportedNumberOfChannelsL"),err );
return err;
}
for (i=0; i<supportedChannels.Count(); i++)
{
if (expectedChannel == supportedChannels[i])
{
TRAP(err, recorder->SetDestinationNumberOfChannelsL(expectedChannel));
if (err)
{
logger->Log(_L("Error %d for SetDestinationNumberOfChannelsL %d"),err, expectedChannel );
return err;
}
break;
}
}
if (i>= supportedChannels.Count())
{
logger->Log(_L("expectedChannel %d is not supported by system, invalid test case."), expectedChannel );
callbackErr = KErrInvalidId;
return callbackErr;
}
/* TRAP(err, recorder->SetDestinationNumberOfChannelsL(expectedChannel));
if (err)
{
logger->Log(_L("Error %d for SetDestinationNumberOfChannelsL %d"),err, expectedChannel );
return err;
}
*/
//Set BitRate
RArray<TUint> supportedBitRates;
TRAP(err, recorder->GetSupportedBitRatesL(supportedBitRates) );
if (err != KErrNone)
{
logger->Log(_L("Error %d for GetSupportedBitRatesL"),err );
return err;
}
for (i=0; i<supportedBitRates.Count(); i++)
{
//TUint bitRate = bitRates[i];
if (expectedBitRate == supportedBitRates[i])
{
TRAP(err, recorder->SetDestinationBitRateL(expectedBitRate));
if (err)
{
logger->Log(_L("Error %d for SetDestinationBitRateL %d"),err, expectedBitRate );
return err;
}
break;
}
}
if (i>= supportedBitRates.Count())
{
logger->Log(_L("expectedSampleRate %d is not supported by system, invalid test case."), expectedSampleRate );
callbackErr = KErrInvalidId;
return callbackErr;
}
}
logger->Log(_L("RecordClip recorder recording"));
TRAP(err,recorder->RecordL());
return err;
}
return KErrNoRecorder;
}
TTimeIntervalMicroSeconds CRecordingBase::Duration()
{
if (recorder)
{
logger->Log(_L("Get Duration, %d") , recorder->Duration().Int64());
return recorder->Duration();
}
else
return TInt64(0);
}
void CRecordingBase::GetFileName(TPtrC path, TFileName* fileName, TInt clipCounter)
{
TBuf<5> num;
num.Format(_L("%d"),clipCounter);
TParse p;
p.Set(path,NULL,NULL);
fileName->Append(p.DriveAndPath());
fileName->Append(p.Name());
fileName->Append(num);
fileName->Append(p.Ext());
}
TInt CRecordingBase::PreProcess(CStifSectionParser* /*aParser*/)
{
if (recorder)
{
recorder->SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal);
recorder->SetGain(recorder->MaxGain());
recorder->SetPosition(TTimeIntervalMicroSeconds(TInt64(0)));
TRAPD(err,recorder->CropL());
if (err != KErrNone) logger->Log(_L("Error cropping file: %d"),err);
}
return KErrNone;
}
TInt CRecordingBase::PostProcess(CStifSectionParser* /*aParser*/)
{
return KErrNone;
}
TInt CRecordingBase::SimpleRecordL(CTestModuleIf* aConsole,
CStifLogger* aLogger,
CRecordingBase* recObj,
TBool doProcess,
CStifSectionParser* aParser,
TBool doTimer)
{
TInt error = KErrNone;
//Start scheduler
if (recObj->maxFileSize != 0)
{
doTimer= false; // since SetMaxWriteLength limits the record time, no timer needed
}
if (doTimer)
{
aLogger->Log(_L("Creating timer"));
//Create timer for stopping recorder
CParameters* params = new CParameters();
CMediaEvent* timer = CMediaEvent::NewL(*aConsole,*aLogger,recObj->timeToRecord,TTimeIntervalMicroSeconds32(0),recObj,params);
CleanupStack::PushL(timer);
}
if (doProcess)
if ((error = recObj->PreProcess(aParser)) != KErrNone)
return error;
TTime iStartTime;
iStartTime.HomeTime();
aLogger->Log(_L("Starting Scheduler"));
CActiveScheduler::Start();
TTime iEndTime;
iEndTime.HomeTime();
TTimeIntervalMicroSeconds PerceivedDuration = iEndTime.MicroSecondsFrom( iStartTime );
aLogger->Log(_L("Perceived duration (%d)") , PerceivedDuration.Int64() );
if (doProcess)
error = recObj->PostProcess(aParser);
if (doTimer) CleanupStack::PopAndDestroy(); // timer
if (error == KErrNone)
return recObj->callbackErr;
return error;
}
TInt CRecordingBase::CreateRecorderL(CTestModuleIf *aConsole,
CStifLogger *aLogger,
CStifSectionParser *aParser,
TInt* clipCounter,
CreateObjectFunction coFunc,
CRecordingBase*& recObj,
TBool nameReq,
TBool sizeReq)
{
TInt error = KErrNone;
recObj = NULL;
TFileName fileName;
TPtrC name;
TTimeIntervalMicroSeconds recTime = KDefaultRecordTime;
TInt maxFileLength = 0;
if (nameReq)
{
//Obtain file name from parser
if (aParser->GetLine(KFileName, name, ENoTag) != KErrNone)
{
aLogger->Log(_L("No file name provided"));
return KErrSyntax;
}
}
CRecordingBase::GetFileName(name,&fileName,*clipCounter);
*clipCounter = *clipCounter + 1;
if (sizeReq)
{
//Obtain record time from parser
CStifItemParser* item = aParser->GetItemLineL(KRecordTime, ENoTag);
if (!item)
{
aLogger->Log(_L("No record time provided, read MaxfileLength"));
item = aParser->GetItemLineL(KMaxLength);
if (!item)
{
aLogger->Log(_L("No MaxfileLength provided either"));
return KErrSyntax;
}
else
{
CleanupStack::PushL(item);
item->GetInt(KMaxLength,maxFileLength);
CleanupStack::PopAndDestroy();
//aLogger->Log(_L("Record time: %d"),recTime.Int64());
aLogger->Log(_L("Maximum recorded file length is: %d"),maxFileLength);
}
}
else
{
CleanupStack::PushL(item);
recTime = CRecordingBase::ParseTime(item);
CleanupStack::PopAndDestroy();
//aLogger->Log(_L("Record time: %d"), recTime.Int64());
LogTime(_L("Record time:"),recTime.Int64(),aLogger);
}
}
//Obtain relative gain(s) from parser and execute test
TInt relativeGain = 0;
CStifItemParser* item = aParser->GetNextItemLineL(KRelativeGain);
// CleanupStack::PushL(item);
if (item)
{
CleanupStack::PushL(item);
error = item->GetInt(KRelativeGain,relativeGain);
if (error != KErrNone)
{
CleanupStack::PopAndDestroy(); // item
aLogger->Log(_L("relative Gain syntax error"));
return error;
}
else
{
//Calculate expected gain
// expectedGain = maxGain*relativeGain/100;
aLogger->Log(_L("Relative gain: %d"),relativeGain);
// aLogger->Log(_L("Relative gain: %d, Value: %d"),relativeGain,expectedGain);
CleanupStack::PopAndDestroy(); // item
}
}
TInt expectedBalance = -999;
item = aParser->GetNextItemLineL(KBalance);
if (item)
{
CleanupStack::PushL(item);
error = item->GetInt(KBalance,expectedBalance);
if (error != KErrNone)
{
CleanupStack::PopAndDestroy(); // item
aLogger->Log(_L("expectedBalance syntax error"));
return error;
}
else
{
aLogger->Log(_L("expectedBalance: %d"),expectedBalance);
CleanupStack::PopAndDestroy(); // item
}
}
TInt expectedBitRate = 0;
item = aParser->GetItemLineL(KBitRate);
if (item)
{
CleanupStack::PushL(item);
error = item->GetInt(KBitRate,expectedBitRate);
if (error != KErrNone)
{
CleanupStack::PopAndDestroy(); // item
aLogger->Log(_L("expectedRitRate syntax error"));
return error;
}
else
{
aLogger->Log(_L("expectedBitRate: %d"),expectedBitRate);
CleanupStack::PopAndDestroy(); // item
}
}
TInt expectedChannel = 1;
item = aParser->GetItemLineL(KChannels);
if (item)
{
CleanupStack::PushL(item);
error = item->GetInt(KChannels,expectedChannel);
if (error != KErrNone)
{
CleanupStack::PopAndDestroy(); // item
aLogger->Log(_L("expectedChannel syntax error"));
return error;
}
else
{
aLogger->Log(_L("expectedChannel: %d"),expectedChannel);
CleanupStack::PopAndDestroy(); // item
}
}
TInt expectedSampleRate = 1;
item = aParser->GetItemLineL(KSampleRate);
if (item)
{
CleanupStack::PushL(item);
error = item->GetInt(KSampleRate,expectedSampleRate);
if (error != KErrNone)
{
CleanupStack::PopAndDestroy(); // item
aLogger->Log(_L("expectedSampleRate syntax error"));
return error;
}
else
{
aLogger->Log(_L("expectedSampleRate: %d"),expectedSampleRate);
CleanupStack::PopAndDestroy(); // item
}
}
//Create recorder
aLogger->Log(_L("Creating recorder"));
recObj = CRecordingBase::NewL(aConsole, aLogger, &fileName, coFunc);
if (!recObj)
{
CleanupStack::PopAndDestroy(); // scheduler
return KErrRecOpenFile;
}
recObj->timeToRecord = recTime;
recObj->recordingFileName = fileName;
recObj->maxFileSize = maxFileLength;
recObj->relativeGain = relativeGain;
recObj->expectedBalance = expectedBalance;
recObj->expectedBitRate = expectedBitRate;
recObj->expectedChannel = expectedChannel;
recObj->expectedSampleRate = expectedSampleRate;
//recObj->isWav = isWav;
//recObj->isAmr = isAmr;
// recObj->isMp4 = isMp4;
aLogger->Log(_L("recObj->timeToRecord:%d"),recObj->timeToRecord);
return error;
}