sl@0: // Copyright (c) 2008-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: #include "char_a3f_devsound_testbase.h" sl@0: #include "char_a3f_devsound_playrecordclients.h" sl@0: #include "char_a3f_devsound_toneclient.h" sl@0: sl@0: const TUint KRateLookup[] = sl@0: { sl@0: EMMFSampleRate8000Hz, sl@0: EMMFSampleRate11025Hz, sl@0: EMMFSampleRate16000Hz, sl@0: EMMFSampleRate22050Hz, sl@0: EMMFSampleRate32000Hz, sl@0: EMMFSampleRate44100Hz, sl@0: EMMFSampleRate48000Hz, sl@0: EMMFSampleRate88200Hz, sl@0: EMMFSampleRate96000Hz, sl@0: EMMFSampleRate12000Hz, sl@0: EMMFSampleRate24000Hz, sl@0: EMMFSampleRate64000Hz sl@0: }; sl@0: sl@0: const TUint KChannelsLookup[] = sl@0: { sl@0: EMMFMono, sl@0: EMMFStereo sl@0: }; sl@0: sl@0: RA3FDevSoundTestBase::RA3FDevSoundTestBase(const TDesC& aTestName) sl@0: : iFourCCString(KNullDesC), sl@0: iFourCCCode(KMMFFourCCCodeNULL), sl@0: iDevSoundState(EStateInitial), sl@0: iDevsoundToneClient(NULL), sl@0: iDevsoundPlayClient(NULL), sl@0: iDevsoundRecordClient(NULL), sl@0: iMMFDevSound(NULL), sl@0: iTimer(NULL), iBuffer(NULL) sl@0: { sl@0: iTestStepName = aTestName; sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::KickoffTestL() sl@0: { sl@0: INFO_PRINTF1(_L("__________ Creating DevSound object ___________")); sl@0: sl@0: // Create devsound object sl@0: TRAPD(err, iMMFDevSound = CMMFDevSound::NewL()); sl@0: if (err != KErrNone) sl@0: { sl@0: ERR_PRINTF2(_L("Could not create DevSound object. Error = %d"), err); sl@0: StopTest(err); sl@0: return; sl@0: } sl@0: INFO_PRINTF1(_L("DevSound State: EStateCreated")); sl@0: iDevSoundState = EStateCreated; sl@0: // Connect RFs sl@0: err = iFs.Connect(); sl@0: if (err != KErrNone) sl@0: { sl@0: ERR_PRINTF2(_L("Could not connect to Filesystem. Error = %d"), err); sl@0: StopTest(err); sl@0: return; sl@0: } sl@0: DoKickoffTestL(); sl@0: INFO_PRINTF1(_L("DevSound Event: EEventInitialize")); sl@0: Fsm(EEventInitialize, KErrNone); sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::CloseTest() sl@0: { sl@0: if (iMMFDevSound) sl@0: { sl@0: INFO_PRINTF1(KMsgDeleteDevsound); sl@0: delete iMMFDevSound; sl@0: } sl@0: if(iTimer) sl@0: { sl@0: delete iTimer; sl@0: } sl@0: if(iDevsoundToneClient) sl@0: { sl@0: delete iDevsoundToneClient; sl@0: } sl@0: if(iDevsoundPlayClient) sl@0: { sl@0: delete iDevsoundPlayClient; sl@0: } sl@0: if(iDevsoundRecordClient) sl@0: { sl@0: delete iDevsoundRecordClient; sl@0: } sl@0: if (iAsyncWriteBTFAO) sl@0: { sl@0: delete iAsyncWriteBTFAO; sl@0: iAsyncWriteBTFAO = NULL; sl@0: } sl@0: sl@0: iFile.Close(); sl@0: iFs.Close(); sl@0: } sl@0: sl@0: /* sl@0: * sl@0: * CallStopTest sl@0: * sl@0: */ sl@0: void RA3FDevSoundTestBase::CallStopTest(TInt aError) sl@0: { sl@0: StopTest(aError); sl@0: } sl@0: sl@0: sl@0: void RA3FDevSoundTestBase::StartTimer(TTimeIntervalMicroSeconds32 aWaitTime) sl@0: { sl@0: TTimeIntervalMicroSeconds32 timeInterval; sl@0: sl@0: if(aWaitTime <= TTimeIntervalMicroSeconds32(0)) sl@0: { sl@0: timeInterval = KMicroSecsInOneSec; sl@0: } sl@0: else sl@0: { sl@0: timeInterval = aWaitTime; sl@0: } sl@0: TCallBack callback (TimerCallback, this); sl@0: iTimer->Start(timeInterval, timeInterval, callback); sl@0: INFO_PRINTF1(_L("Timer has been started")); sl@0: } sl@0: sl@0: TInt RA3FDevSoundTestBase::TimerCallback(TAny* aPtr) sl@0: { sl@0: static_cast(aPtr)->DoTimerCallback(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::DoTimerCallback() sl@0: { sl@0: __ASSERT_ALWAYS(0, Panic(_L("RA3FDevSoundTestBase"), EInvalidCallbackCall)); sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::EncodingFromStringToTFourCC(const TDesC& aFourCCString) sl@0: { sl@0: iFourCCString.Copy(aFourCCString); sl@0: if(aFourCCString.Length() <= KTFourCC) sl@0: { sl@0: while( iFourCCString.Length() < KTFourCC ) sl@0: { sl@0: iFourCCString.Insert(0, _L(" ")); sl@0: } sl@0: iFourCCCode = TFourCC(iFourCCString[3] << 24 | iFourCCString[2] << 16 | iFourCCString[1] << 8 | iFourCCString[0]); sl@0: } sl@0: else sl@0: { sl@0: ERR_PRINTF2(KMsgErrorFourccLength,iFourCCString.Length()); sl@0: StopTest(KErrUnknown); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::InitializeComplete(TInt aError) sl@0: { sl@0: INFO_PRINTF1(_L("========== DevSound InitializeComplete() callback ==========")); sl@0: INFO_PRINTF3(KMsgErrorDevSoundCallback, &KInitializeCompleteText, aError); sl@0: if(iDevSoundState == EStateInitializing) sl@0: { sl@0: INFO_PRINTF1(_L("DevSound Event: EEventInitComplete")); sl@0: Fsm(EEventInitComplete, aError); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::ToneFinished(TInt aError) sl@0: { sl@0: INFO_PRINTF1(_L("========== DevSound ToneFinished() callback ==========")); sl@0: if (aError == KErrUnderflow) sl@0: { sl@0: INFO_PRINTF2(_L("DevSound called CMMFDevSound::ToneFinished with error = %d as expected"), aError); sl@0: StopTest(aError,EPass); sl@0: } sl@0: else sl@0: { sl@0: ERR_PRINTF2(_L("DevSound called CMMFDevSound::ToneFinished with error = %d"), aError); sl@0: ERR_PRINTF2(_L("Expected error = %d"), KErrUnderflow); sl@0: StopTest(aError); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::BufferToBeFilled(CMMFBuffer* aBuffer) sl@0: { sl@0: INFO_PRINTF1(_L("========== DevSound BufferToBeFilled() callback ==========")); sl@0: if (!aBuffer) sl@0: { sl@0: ERR_PRINTF1(_L("BufferToBeFilled callback received a NULL CMMFBuffer!")); sl@0: StopTest(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: iBuffer = aBuffer; sl@0: INFO_PRINTF1(_L("DevSound Event: EEventBTBF")); sl@0: Fsm(EEventBTBF, KErrNone); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::PlayError(TInt aError) sl@0: { sl@0: INFO_PRINTF1(_L("========== DevSound PlayError() callback ==========")); sl@0: INFO_PRINTF3(KMsgErrorDevSoundCallback, &KPlayErrorText, aError); sl@0: if(iBuffer->LastBuffer() && (aError == KErrUnderflow)) sl@0: { sl@0: INFO_PRINTF1(_L("Playback completed normally")); sl@0: StopTest(); sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("Playback completed with error")); sl@0: StopTest(aError, EFail); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::BufferToBeEmptied(CMMFBuffer* aBuffer) sl@0: { sl@0: INFO_PRINTF1(_L("DevSound called BufferToBeEmptied.")); sl@0: if (!aBuffer) sl@0: { sl@0: INFO_PRINTF1(_L("BufferToBeEmptied callback received a NULL CMMFBuffer")); sl@0: StopTest(KErrGeneral); sl@0: return; sl@0: } sl@0: iBuffer = aBuffer; sl@0: if(aBuffer->LastBuffer()) sl@0: { sl@0: if(iDevSoundState == EStatePause) sl@0: { sl@0: // We need to call CMMFDevSound->Stop() here if last buffer flag set sl@0: INFO_PRINTF1(_L("Devsound is in Paused state and CMMFBuffer::LastBuffer is set")); sl@0: INFO_PRINTF1(_L("iMMFDevSound->Stop()")); sl@0: iMMFDevSound->Stop(); sl@0: StopTest(); sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("***** Unknown behaviour: Last buffer flag set before calling CMMFDevSound->Pause()")); sl@0: StopTest(KErrUnknown); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("DevSound Event: EEventBTBE")); sl@0: Fsm(EEventBTBE, KErrNone); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::RecordError(TInt aError) sl@0: { sl@0: INFO_PRINTF2(_L("DevSound called RecordError with error = %d"), aError); sl@0: if (aError == KErrUnderflow) sl@0: { sl@0: StopTest(aError); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::ConvertError(TInt /*aError*/) sl@0: { sl@0: __ASSERT_ALWAYS(0, Panic(_L("RA3FDevSoundTestBase"), EInvalidCallbackCall)); sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/) sl@0: { sl@0: __ASSERT_ALWAYS(0, Panic(_L("RA3FDevSoundTestBase"), EInvalidCallbackCall)); sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::SendEventToClient(const TMMFEvent& aEvent) sl@0: { sl@0: INFO_PRINTF3(_L("RA3FDevSoundTestBase::SendEventToClient type=0x%08x errorCode=%d"),aEvent.iEventType, aEvent.iErrorCode); sl@0: if(aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable) sl@0: { sl@0: INFO_PRINTF1(_L("Received KMMFEventCategoryAudioResourceAvailable")); sl@0: Fsm(EResourceAvailable, aEvent.iErrorCode); sl@0: } sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::SampleRateFromTIntToTMMFSampleRate(TInt aSampleRate, TMMFSampleRate &aESampleRate) sl@0: { sl@0: const TSampleRateToTMMFSampleRate SampleRateLookUp [] = sl@0: { sl@0: {8000, EMMFSampleRate8000Hz}, sl@0: {11025, EMMFSampleRate11025Hz}, sl@0: {16000, EMMFSampleRate16000Hz}, sl@0: {22050, EMMFSampleRate22050Hz}, sl@0: {32000, EMMFSampleRate32000Hz}, sl@0: {44100, EMMFSampleRate44100Hz}, sl@0: {48000, EMMFSampleRate48000Hz}, sl@0: {88200, EMMFSampleRate88200Hz}, sl@0: {96000, EMMFSampleRate96000Hz}, sl@0: {12000, EMMFSampleRate12000Hz}, sl@0: {24000, EMMFSampleRate24000Hz}, sl@0: {64000, EMMFSampleRate64000Hz} sl@0: }; sl@0: sl@0: const TInt length = sizeof SampleRateLookUp / sizeof *SampleRateLookUp; sl@0: sl@0: for(TInt i = 0; i < length; i++) sl@0: { sl@0: if(aSampleRate == SampleRateLookUp[i].iTIntSampleRate) sl@0: { sl@0: aESampleRate = SampleRateLookUp[i].iTMMFSampleRate; sl@0: return; sl@0: } sl@0: } sl@0: ERR_PRINTF1(_L("User SampleRate doesn't match any of the specified sample rates")); sl@0: StopTest(KErrGeneral); sl@0: } sl@0: sl@0: sl@0: void RA3FDevSoundTestBase::SampleRateFromTUintToString(TUint aSampleRate, TDes& aStringSampleRate) sl@0: { sl@0: const TSampleRateToString SampleRateLookUp [] = sl@0: { sl@0: {0x00000001, KEMMFSampleRate8000Hz() }, sl@0: {0x00000002, KEMMFSampleRate11025Hz()}, sl@0: {0x00000004, KEMMFSampleRate16000Hz()}, sl@0: {0x00000008, KEMMFSampleRate22050Hz()}, sl@0: {0x00000010, KEMMFSampleRate32000Hz()}, sl@0: {0x00000020, KEMMFSampleRate44100Hz()}, sl@0: {0x00000040, KEMMFSampleRate48000Hz()}, sl@0: {0x00000080, KEMMFSampleRate88200Hz()}, sl@0: {0x00000100, KEMMFSampleRate96000Hz()}, sl@0: {0x00000200, KEMMFSampleRate12000Hz()}, sl@0: {0x00000400, KEMMFSampleRate24000Hz()}, sl@0: {0x00000800, KEMMFSampleRate64000Hz()} sl@0: }; sl@0: sl@0: const TInt length = sizeof SampleRateLookUp / sizeof *SampleRateLookUp; sl@0: sl@0: for (TInt i =0; i < length; i++) sl@0: { sl@0: if(aSampleRate == SampleRateLookUp[i].iTUIntSampleRate) sl@0: { sl@0: aStringSampleRate.Copy(SampleRateLookUp[i].iTPtrSampleRate); sl@0: return; sl@0: } sl@0: } sl@0: ERR_PRINTF1(_L("SampleRate doesn't match any of the specified sample rates")); sl@0: StopTest(KErrGeneral); sl@0: } sl@0: sl@0: void RA3FDevSoundTestBase::ChannelsFromTUintToString(TUint aChannels,TDes& aStringChannels) sl@0: { sl@0: const TChannelsToString ChannelsLookUp [] = sl@0: { sl@0: {0x00000001, KEMMFMono() }, sl@0: {0x00000002, KEMMFStereo()}, sl@0: }; sl@0: const TInt length = sizeof ChannelsLookUp / sizeof *ChannelsLookUp; sl@0: sl@0: for (TInt i =0; i < length; i++) sl@0: { sl@0: if(aChannels == ChannelsLookUp[i].iTUIntChannels) sl@0: { sl@0: aStringChannels.Copy(ChannelsLookUp[i].iTPtrChannels); sl@0: return; sl@0: } sl@0: } sl@0: ERR_PRINTF1(_L("Channels doesn't match any of the specified channels")); sl@0: StopTest(KErrGeneral); sl@0: } sl@0: sl@0: sl@0: void RA3FDevSoundTestBase::PrintSupportedCapabilities(TUint aSampleRate,TUint aChannel) sl@0: { sl@0: TInt length = sizeof KRateLookup / sizeof *KRateLookup; sl@0: TBuf stringSampleRate; sl@0: TBuf channels; sl@0: sl@0: for(TInt i = 0; i < length ; i++) sl@0: { sl@0: if(aSampleRate & KRateLookup[i]) sl@0: { sl@0: SampleRateFromTUintToString(KRateLookup[i],stringSampleRate); sl@0: INFO_PRINTF3(_L("Supported Sample rate 0x%08x %S"),KRateLookup[i],&stringSampleRate); sl@0: } sl@0: } sl@0: length = sizeof KChannelsLookup / sizeof *KChannelsLookup; sl@0: sl@0: for(TInt i = 0; i < length ; i++) sl@0: { sl@0: if(aChannel & KChannelsLookup[i]) sl@0: { sl@0: ChannelsFromTUintToString(KChannelsLookup[i],channels); sl@0: INFO_PRINTF3(_L("Supported channels 0x%08x %S"),KChannelsLookup[i],&channels); sl@0: } sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CAsyncWriteBufferToFile sl@0: // sl@0: sl@0: CAsyncWriteBufferToFile::CAsyncWriteBufferToFile(RFile& aFile, CMMFDevSound* aDevSound, RA3FDevSoundTestBase& aTestStep) sl@0: :CActive(EPriorityStandard), sl@0: iFile(aFile), sl@0: iDevSound(aDevSound), sl@0: iTestStep(aTestStep) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CAsyncWriteBufferToFile::~CAsyncWriteBufferToFile() sl@0: { sl@0: Cancel(); sl@0: } sl@0: sl@0: CAsyncWriteBufferToFile* CAsyncWriteBufferToFile::NewL(RFile& aFile, CMMFDevSound* aDevSound, RA3FDevSoundTestBase& aTestStep) sl@0: { sl@0: CAsyncWriteBufferToFile* self = new(ELeave) CAsyncWriteBufferToFile(aFile, aDevSound, aTestStep); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: void CAsyncWriteBufferToFile::ConstructL() sl@0: { sl@0: // Nothing to do here sl@0: } sl@0: sl@0: void CAsyncWriteBufferToFile::RunL() sl@0: { sl@0: //If error occurs then deal with problem in RunError() sl@0: User::LeaveIfError(iStatus.Int()); sl@0: // Continue recording data to a buffer sl@0: iDevSound->RecordData(); sl@0: sl@0: } sl@0: sl@0: void CAsyncWriteBufferToFile::Start(CMMFDataBuffer* aBuffer) sl@0: { sl@0: iFile.Write(aBuffer->Data(), iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CAsyncWriteBufferToFile::DoCancel() sl@0: { sl@0: // Can't cancel an async write request sl@0: } sl@0: sl@0: TInt CAsyncWriteBufferToFile::RunError(TInt aError) sl@0: { sl@0: iTestStep.CallStopTest(aError); sl@0: return KErrNone; sl@0: }