sl@0: // Copyright (c) 2006-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: 
sl@0: 
sl@0: #include "cdevaudiocontrol.h"
sl@0: 
sl@0: #include <a3f/audioprocessingunittypeuids.h>
sl@0: #include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh>
sl@0: #include <a3f/maudiocontext.h>
sl@0: #include <a3f/maudiostream.h>
sl@0: #include <a3f/maudiocodec.h>
sl@0: #include <a3f/maudiogaincontrol.h>
sl@0: 
sl@0: 
sl@0: const TInt KMicroSecondsInSecond = 1000000;
sl@0: const TInt KDefaultBufferSize = 4096;
sl@0: 
sl@0: const TUint KMaxCallbacksExpected = 2;
sl@0: const TUint KDefaultSampleRate = 8000;
sl@0: const TUid KDefaultMode = {KA3FModeMonoValue};
sl@0: 
sl@0: class TSampleRateTableEntry
sl@0: 	{
sl@0: public:
sl@0: 	TInt		iSampleRateValue;
sl@0: 	TMMFSampleRate iSampleRate;
sl@0: 	};
sl@0: 
sl@0: const TSampleRateTableEntry KRateTableLookup[] = { 
sl@0: 							{ 8000, EMMFSampleRate8000Hz },
sl@0: 							{ 11025, EMMFSampleRate11025Hz },
sl@0: 							{ 12000, EMMFSampleRate12000Hz },
sl@0: 							{ 16000, EMMFSampleRate16000Hz },
sl@0: 							{ 22050, EMMFSampleRate22050Hz },
sl@0: 							{ 24000, EMMFSampleRate24000Hz },
sl@0: 							{ 32000, EMMFSampleRate32000Hz },
sl@0: 							{ 44100, EMMFSampleRate44100Hz },
sl@0: 							{ 48000, EMMFSampleRate48000Hz },
sl@0: 							{ 64000, EMMFSampleRate64000Hz },
sl@0: 							{ 88200, EMMFSampleRate88200Hz },
sl@0: 							{ 96000, EMMFSampleRate96000Hz },
sl@0: 						};
sl@0: const TInt KMaxSampleRateIndex = 11; // must agree with length of table
sl@0: 
sl@0: class TAudioModeTableEntry
sl@0: 	{
sl@0: public:
sl@0: 	TMMFMonoStereo	iAudioModeValue;
sl@0: 	TUid			iAudioMode;
sl@0: 	};
sl@0: 
sl@0: const TAudioModeTableEntry KModeTableLookup[] = {
sl@0: 							{ EMMFMono, {KA3FModeMonoValue} },
sl@0: 							{ EMMFStereo, {KA3FModeStereoNonInterleavedValue} },
sl@0: 							};
sl@0: 
sl@0: const TInt KMaxModeIndex = 1; // must agree with length of table
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // Default constructor
sl@0: // ---------------------------------------------------------------------------
sl@0: //
sl@0: CDevAudioControl::CDevAudioControl()
sl@0: 	{
sl@0: 	TRACE_CREATE();
sl@0: 	DP_CONTEXT(CDevAudioControl::CDevAudioControl *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	// Local cache default values
sl@0: 	iCurrentSampleRate = KDefaultSampleRate;
sl@0: 	iCurrentMode = KDefaultMode; 
sl@0: 	iOutstandingCallbacks = KMaxCallbacksExpected; //by default we expect 2 callbacks for capabilities.
sl@0: 	iCallbackFromAdaptor = KCallbackNone;
sl@0: 	
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CDevAudioControl::ConstructL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aDevSoundObserver)
sl@0: 	{
sl@0: 	TRACE_CREATE();
sl@0: 	DP_CONTEXT(CDevAudioControl::ConstructL *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	iDevAudio = aDevAudio; 
sl@0: 	iAdaptationObserver = &aDevSoundObserver;
sl@0: 	
sl@0: 	iObserverRegistered = EFalse;
sl@0: 
sl@0: 	TAudioChannelGain left;
sl@0: 	TAudioChannelGain right;
sl@0: 	
sl@0: 	left.iLocation = TAudioChannelGain::ELeft;
sl@0: 	right.iLocation = TAudioChannelGain::ERight;
sl@0: 		
sl@0: 	User::LeaveIfError(iChannelGains.Append(left)); // assumed element 0 in rest of code
sl@0: 	User::LeaveIfError(iChannelGains.Append(right)); // assumed element 1 in rest of code
sl@0: 
sl@0: 	// Note this could be delayed now (volume is internal to adaptor until later in cycle)
sl@0: 	// Needed to allow CMMFDevSound::MaxVolume and similar calls before CMMFDevSound::InitializeL
sl@0: 	TAny* interface(NULL);
sl@0: 	interface = iDevAudio->iGainControl->Interface(KUidAudioGainControl);
sl@0: 	iGainControl = static_cast<MAudioGainControl*>(interface);
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // Destructor
sl@0: // ---------------------------------------------------------------------------
sl@0: //
sl@0: CDevAudioControl::~CDevAudioControl()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::~CDevAudioControl *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	iChannelGains.Close();
sl@0: 	iSupportedRates.Close();
sl@0: 	iSupportedModes.Close();
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 	
sl@0: // -----------------------------------------------------------------------------
sl@0: // CacheAudioCodecIf
sl@0: //
sl@0: TInt CDevAudioControl::CacheAudioCodecIf()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::CacheAudioCodecIf *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	if (iDevAudio->iAudioCodec==NULL)
sl@0: 		{
sl@0: 		DP0_RET(KErrNotReady,"%d");
sl@0: 		}
sl@0: 	TInt err = KErrNone;
sl@0: 	if (iAudioCodecIf==NULL)
sl@0: 		{
sl@0: 		MAudioCodec* codecInterface = static_cast<MAudioCodec*>(iDevAudio->iAudioCodec->Interface(KUidAudioCodec));
sl@0: 		__ASSERT_ALWAYS (codecInterface, CDevAudioControl::Panic(EAudioCodecIsNull));
sl@0: 		iAudioCodecIf = codecInterface; 
sl@0: 		}
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::Initialize
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::Initialize(TUid /*aFormat*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Initialize *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	iObserverRegistered = EFalse;
sl@0: 	DP0_RET(KErrNone,"%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::Uninitialize
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::Uninitialize()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Uninitialize *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	// Remove pUnits only allowed when stream is uninitialized
sl@0: 	TInt err = iDevAudio->iAudioStream->Uninitialize();
sl@0: 
sl@0: 	if (err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->CommitAudioContext();
sl@0: 		}
sl@0: 	if (err == KErrNone)
sl@0: 		{
sl@0: 		iDevAudio->iActiveState = EDevSoundAdaptorUninitialising;
sl@0: 		}
sl@0: 
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::Unload
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::Unload()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Unload *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	TInt err = iDevAudio->iAudioStream->Unload();
sl@0: 	if (err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->CommitAudioContext();
sl@0: 		}
sl@0: 	if (err == KErrNone)
sl@0: 		{
sl@0: 		iDevAudio->iActiveState = EDevSoundAdaptorUnloading;
sl@0: 		}
sl@0: 
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetCapabilities
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::GetCapabilities(TMMFCapabilities& aCap)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetCapabilities *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	// At this phase of CAP, we only care about current codec capabilities. 
sl@0: 	// This will be supported as soon as the A3F API changes to support this are ready
sl@0: 	TInt err = KErrNone;
sl@0: 		
sl@0: 	if (iDevAudio->iActiveState != EDevSoundAdaptorCreated_Uninitialised)
sl@0: 		{
sl@0: 		err = CacheAudioCodecIf();
sl@0: 		if (err != KErrNone)
sl@0: 			{
sl@0: 			DP0_RET(err, "%d");			
sl@0: 			}
sl@0: 			
sl@0: 		if (err == KErrNone)
sl@0: 			{
sl@0: 			err = iAudioCodecIf->GetSupportedModes(iSupportedModes);
sl@0: 			if (err == KErrNone)
sl@0: 				{
sl@0: 				aCap.iChannels = GetModes(iSupportedModes);
sl@0: 				err = iAudioCodecIf->GetSupportedSamplesRates(iSupportedRates);
sl@0: 				
sl@0: 				if (err == KErrNone)
sl@0: 					{
sl@0: 					aCap.iRate = GetSampleRates(iSupportedRates);
sl@0: 					}
sl@0: 				else
sl@0: 					{
sl@0: 					//If was a problem getting sampleRates we don´t expect callbacks and return
sl@0: 					iOutstandingCallbacks = 0;
sl@0: 					}
sl@0: 					
sl@0: 				}
sl@0: 			else
sl@0: 				{
sl@0: 				//If was a problem getting modes we don´t expect callbacks and return
sl@0: 				iOutstandingCallbacks = 0;
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		err = KErrNotReady;
sl@0: 		}
sl@0: 	DP0_RET(err, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetConfig
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::GetConfig(TMMFCapabilities& aConfig)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetConfig *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TInt err(KErrNone);
sl@0: 
sl@0: 	//TODO add a return error code if the sample rate or the channels are not found
sl@0: 	//We need to transform the local values to a supported value for the client
sl@0: 	aConfig.iRate = static_cast<TMMFSampleRate>(GetSampleRate(iCurrentSampleRate));
sl@0: 	aConfig.iChannels = static_cast<TMMFMonoStereo>(GetMode(iCurrentMode));
sl@0: 	aConfig.iBufferSize = KDefaultBufferSize;
sl@0: 	
sl@0: 	DP2(DLINFO, "rate 0x%x, channels 0x%x", aConfig.iRate, aConfig.iChannels);
sl@0: 
sl@0: 	DP0_RET(err, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::SetConfig
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::SetConfig(const TMMFCapabilities& aConfig)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::SetConfig *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	
sl@0: 	// TODO need to ensure if iChannels or iSampleRate is outside known values, then
sl@0: 	// the code handles that gracefully and returns the appropriate error code
sl@0: 	
sl@0: 	TInt err(KErrNone);
sl@0: 	TUid mode = KNullUid;
sl@0: 	//Reset the desired values
sl@0: 	iDesiredSampleRate = 0;
sl@0: 	iDesiredMode = KNullUid;
sl@0: 
sl@0: 	err = ResolveMode(aConfig.iChannels, mode);
sl@0: 	if (err != KErrNone)
sl@0: 		{
sl@0: 		DP0_RET(err, "%d");
sl@0: 		}
sl@0: 
sl@0: 	err = ResolveSampleRate(aConfig.iRate, iDesiredSampleRate);
sl@0: 	if (err != KErrNone)
sl@0: 		{
sl@0: 		DP0_RET(err, "%d");
sl@0: 		}
sl@0: 
sl@0: 	// At this phase of CAP, we only care about codec, which checks config against
sl@0: 	// its own capabilities. Verification against stream specific capabilities
sl@0: 	// should be added later on.
sl@0: 	
sl@0: 	err = CacheAudioCodecIf();
sl@0: 	if (err != KErrNone)
sl@0: 		{
sl@0: 		DP0_RET(err, "%d");
sl@0: 		}
sl@0: 	
sl@0: 	err = iAudioCodecIf->SetSampleRate(iDesiredSampleRate);
sl@0: 		
sl@0: 	
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		err = iAudioCodecIf->SetMode(mode);
sl@0: 		}
sl@0: 	
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->CommitAudioContext();
sl@0: 		if (err == KErrNone)
sl@0: 			{
sl@0: 			iDesiredMode = mode;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	DP0_RET(err, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::ProcessInit
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::ProcessInit()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::ProcessInit *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP0_RET(KErrNone,"%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::ProcessData
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::ProcessData()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::ProcessData *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetSamples
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::GetSamples()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetSamples *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TInt err(KErrNone);
sl@0: 	TInt samplesplayed(0);
sl@0: 	
sl@0: 	TTimeIntervalMicroSeconds timeProcessed(0);
sl@0: 	err = iDevAudio->iAudioStream->GetStreamTime(timeProcessed);
sl@0: 
sl@0: 	DP1(DLINFO,"CDevAudioControl::GetSamples iCurrentSampleRate %d",iCurrentSampleRate);
sl@0: 	
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		samplesplayed = (timeProcessed.Int64() * iCurrentSampleRate + KMicroSecondsInSecond/2) / TInt64(KMicroSecondsInSecond);
sl@0: 		}
sl@0: 	//TODO manage the error
sl@0: 
sl@0: 	DP0_RET(samplesplayed, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::Stop
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::Stop()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Stop *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP0_RET(KErrNone, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::Pause
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::Pause()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Pause *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP0_RET(KErrNone, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::CustomInterface
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TAny* CDevAudioControl::CustomInterface(TUid aInterfaceId)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::CustomInterface *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TAny* ciPtr(NULL);
sl@0: 	TInt err = KErrNone;
sl@0: 	if(iDevAudio->iAudioStream)
sl@0: 		{
sl@0: 		TAny* ptr = iDevAudio->iAudioStream->Interface(KUidExtensionInferface);
sl@0: 		if(ptr)
sl@0: 			{
sl@0: 			MCustomInterfaceSupport* ciSupport  = static_cast<MCustomInterfaceSupport*>(ptr);
sl@0: 			if(!iObserverRegistered)
sl@0: 				{
sl@0: 				err = ciSupport->RegisterObserver(*this);
sl@0: 				if(err == KErrNone)
sl@0: 					{
sl@0: 					iObserverRegistered = ETrue;
sl@0: 					}
sl@0: 				}
sl@0: 			err = ciSupport->RequestCustomInterface(aInterfaceId, ciPtr);
sl@0: 			if( err != KErrNone)
sl@0: 				{
sl@0: 				ciPtr = NULL;
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 	DP0_RET(ciPtr, "0x%x");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::SetGain
sl@0: // -----------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::SetGains(TInt aDevSoundGain, TInt aDevSoundMaxGain, TInt aBalance[2], const TTimeIntervalMicroSeconds& aRampDuration, TBool aBecomingActive)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::SetGains *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(aDevSoundGain>=0 && aDevSoundGain<=aDevSoundMaxGain); // higher layer assumed to scale
sl@0: 	ASSERT(aBalance[ELeftCh]>=0 && aBalance[ELeftCh]<=100);
sl@0: 	ASSERT(aBalance[ERightCh]>=0 && aBalance[ERightCh]<=100);
sl@0: 	ASSERT(aDevSoundMaxGain>0); // assumed max gain is positive
sl@0: 	TInt a3fMaxGain;
sl@0: 	TInt err = iGainControl->GetMaxGain(a3fMaxGain);
sl@0: 	if (err==KErrNone)
sl@0: 		{
sl@0: 		iLegacyGain = TInt(TReal(aDevSoundGain)*TReal(a3fMaxGain)/TReal(aDevSoundMaxGain)+0.5);
sl@0: 		ASSERT(iLegacyGain>=0 && iLegacyGain<=a3fMaxGain);
sl@0: 		iLegacyLeft = aBalance[ELeftCh];
sl@0: 		iLegacyRight = aBalance[ERightCh];
sl@0: 
sl@0: 		MapGains();
sl@0: 
sl@0: 		// VolumeRamp is only applied when DevSound is becoming active
sl@0: 		if(err == KErrNone)
sl@0: 			{
sl@0: 			if (aRampDuration > 0 && aBecomingActive)
sl@0: 				{
sl@0: 				err = iGainControl->SetGain(iChannelGains, KUidGainSawTooth, aRampDuration);
sl@0: 				}
sl@0: 			else
sl@0: 				{
sl@0: 				err = iGainControl->SetGain(iChannelGains);
sl@0: 				}
sl@0: 			}
sl@0: 
sl@0: 		// This call will result on commit only when we are already active
sl@0: 		// otherwise the changes will be commited by the DevAudioControl 
sl@0: 		// It means we're here due to RequestGainAndBalance call
sl@0: 		if(err == KErrNone && !aBecomingActive)
sl@0: 			{
sl@0: 			err = iDevAudio->CommitAudioContext();
sl@0: 			}		
sl@0: 		}
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::MapAndSetGains
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::MapGains()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::MapGains *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	// Map legacy values to CAP channel array.
sl@0: 	if ( iLegacyLeft == iLegacyRight )
sl@0: 		{
sl@0: 		iChannelGains[ELeftCh].iGain = iLegacyGain;
sl@0: 		iChannelGains[ERightCh].iGain = iLegacyGain;
sl@0: 		}
sl@0: 	else if ( iLegacyLeft > iLegacyRight )
sl@0: 		{
sl@0: 		iChannelGains[ELeftCh].iGain = iLegacyGain;
sl@0: 		iChannelGains[ERightCh].iGain =
sl@0: 						static_cast<TUint>((iLegacyGain*iLegacyRight)/iLegacyLeft);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		iChannelGains[ERightCh].iGain = iLegacyGain;
sl@0: 		iChannelGains[ELeftCh].iGain =
sl@0: 						static_cast<TUint>((iLegacyGain*iLegacyLeft)/iLegacyRight);
sl@0: 		}
sl@0: 
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::DestroyChain
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TBool CDevAudioControl::DestroyChain()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::DestroyChain *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	TInt err = KErrNone;
sl@0: 	TBool readyToDestroy = EFalse;
sl@0: 	switch(iDevAudio->iActiveState)
sl@0: 		{
sl@0: 		case EDevSoundAdaptorActive_Active:
sl@0: 		case EDevSoundAdaptorPaused_Primed:
sl@0: 			{
sl@0: 			err = iDevAudio->iAudioStream->Stop();
sl@0: 			if(err == KErrNone)
sl@0: 				{
sl@0: 				err = iDevAudio->CommitAudioContext();
sl@0: 				}
sl@0: 			if (err == KErrNone)
sl@0: 				{
sl@0: 				iDevAudio->iActiveState = EDevSoundAdaptorStopping;
sl@0: 				}
sl@0: 			}
sl@0: 			break;
sl@0: 		case EDevSoundAdaptorInitialised_Idle:
sl@0: 			{
sl@0: 			err = iDevAudio->iAudioStream->Unload();
sl@0: 			if(err == KErrNone)
sl@0: 				{
sl@0: 				err = iDevAudio->CommitAudioContext();
sl@0: 				}
sl@0: 			if (err == KErrNone)
sl@0: 				{
sl@0: 				iDevAudio->iActiveState = EDevSoundAdaptorUnloading;
sl@0: 				}
sl@0: 			}
sl@0: 			break;
sl@0: 		case EDevSoundAdaptorInitialised_Initialised:
sl@0: 			{
sl@0: 			err = iDevAudio->iAudioStream->Uninitialize();
sl@0: 			if(err == KErrNone)
sl@0: 				{
sl@0: 				err = iDevAudio->CommitAudioContext();
sl@0: 				}
sl@0: 			if (err == KErrNone)
sl@0: 				{
sl@0: 				iDevAudio->iActiveState = EDevSoundAdaptorUninitialising;
sl@0: 				}
sl@0: 			}
sl@0: 			break;
sl@0: 		case EDevSoundAdaptorCreated_Uninitialised:
sl@0: 			readyToDestroy = ETrue;
sl@0: 			break;
sl@0: 		case EDevSoundAdaptorUnitialised_Uninitialised:
sl@0: 			//If following condition is true, then we are here because of a
sl@0: 			//pre-emption clash in last Commit cycle started from
sl@0: 			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
sl@0: 			if(iDevAudio->iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
sl@0: 				{
sl@0: 				err = RemoveProcessingUnits();
sl@0: 				break;
sl@0: 				}
sl@0: 		default:
sl@0: 			break;
sl@0: 		}
sl@0: 	
sl@0: 	// Destroy sequence fail!
sl@0: 	if(err != KErrNone)
sl@0: 		{
sl@0: 		DP0(DLINFO, "================ Destroy sequence fail! ================");
sl@0: 		readyToDestroy = ETrue;
sl@0: 		}
sl@0: 	// Set the flag only when needed
sl@0: 	iDevAudio->iClosing = !readyToDestroy;
sl@0: 	DP0_RET(readyToDestroy,"%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::RemoveProcessingUnits
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::RemoveProcessingUnits()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::RemoveProcessingUnits *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	// Remove pUnits only allowed when stream is uninitialized
sl@0: 	TInt err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioSource);
sl@0: 		
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioSink);	
sl@0: 		}
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioCodec);
sl@0: 		}
sl@0: 
sl@0: 	if (err == KErrNone)
sl@0: 		{
sl@0: 		err = iDevAudio->CommitAudioContext();
sl@0: 		}
sl@0: 		
sl@0: 	if(err == KErrNone)
sl@0: 		{
sl@0: 		iDevAudio->iActiveState = EDevSoundAdaptorRemovingProcessingUnits;		
sl@0: 		}
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioStreamObserver
sl@0: // CDevAudioControl::StateEvent
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::StateEvent(MAudioStream& /*aStream*/, 
sl@0: 									TInt /*aReason*/, 
sl@0: 									TAudioState /*aNewState*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudio::StateEvent *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioStreamObserver
sl@0: // CDevAudioControl::AddProcessingUnitComplete
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::AddProcessingUnitComplete(MAudioStream& /*aStream*/, 
sl@0: 												MAudioProcessingUnit* /*aInstance*/,
sl@0: 												TInt /*aError*/)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioStreamObserver
sl@0: // CDevAudioControl::RemoveProcessingUnitComplete
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::RemoveProcessingUnitComplete(MAudioStream& /*aStream*/,
sl@0: 													MAudioProcessingUnit* /*aInstance*/,
sl@0: 													TInt /*aError*/)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioStreamObserver
sl@0: // CDevAudioControl::ProcessingFinished
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::ProcessingFinished(MAudioStream& /*aStream*/)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioStreamObserver
sl@0: // CDevAudioControl::FlushComplete
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::FlushComplete (MAudioStream& /*aStream*/, TInt aError)
sl@0: 	{
sl@0: 	// no action needed - should complete as part of the ContextEvent.
sl@0: 	// otherwise could callback.
sl@0: 	TInt err = KErrNone;
sl@0: 	
sl@0: 	if(iPauseResumeSequenceDueToEmptyBuffers)
sl@0: 		{
sl@0: 		// Flush operation failed
sl@0: 		if(aError != KErrNone)
sl@0: 			{
sl@0: 			iPauseResumeSequenceDueToEmptyBuffers = EFalse;
sl@0: 			iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
sl@0: 			}
sl@0: 		// Handle throw-off scenarios, resume is not possible from here
sl@0: 		// 1. ProcessingFinished has occurred
sl@0: 		// 2. Preemption occurred 
sl@0: 		else if(iCallbackFromAdaptor != KCallbackNone || 
sl@0: 			iDevAudio->iActiveState != EDevSoundAdaptorPaused_Primed)
sl@0: 			{
sl@0: 			iPauseResumeSequenceDueToEmptyBuffers = EFalse;
sl@0: 			iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, KErrNone);
sl@0: 			
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			err = Resume();
sl@0: 			if(err != KErrNone)
sl@0: 				{
sl@0: 				iPauseResumeSequenceDueToEmptyBuffers = EFalse;
sl@0: 				iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
sl@0: 				}
sl@0: 			// Once ContextEvent be received 
sl@0: 			// EmptyBuffers can be considered completed
sl@0: 			}
sl@0: 		}
sl@0: 	// EmptyBuffers operation has concluded here
sl@0: 	// we didn't go through pause - resume sequence
sl@0: 	else
sl@0: 		{
sl@0: 		iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
sl@0: 		}
sl@0: 	}
sl@0: 	
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioGainControlObserver
sl@0: // CDevAudioControl::MaxRampTimeChanged
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::MaxRampTimeChanged(MAudioGainControl& /*aGain*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::MaxRampTimeChanged *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	// this is not cached, no actions needed
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioGainControlObserver
sl@0: // CDevAudioControl::MaxGainChanged
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::MaxGainChanged(MAudioGainControl& /*aGain*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::MaxGainChanged *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	// this is not cached, no actions needed
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioGainControlObserver
sl@0: // CDevAudioControl::GainChanged
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::GainChanged(MAudioGainControl& aGain, TInt aError)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GainChanged *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP1_IN("aError=%d", aError);
sl@0: 
sl@0: 	if(aError != KErrNone)
sl@0: 		{
sl@0: 		// Either our request failed, or MMRC has forced some values, and we
sl@0: 		// have to update local values.
sl@0: 		aGain.GetGain(iChannelGains);
sl@0: 		ASSERT(iChannelGains.Count()==2);
sl@0: 		// Map CAP channel array to legacy values. 
sl@0: 		// assumption: left%+right%=100
sl@0: 		if ( iChannelGains[ELeftCh].iGain == iChannelGains[ERightCh].iGain )
sl@0: 			{
sl@0: 			iLegacyGain = iChannelGains[ELeftCh].iGain;
sl@0: 			iLegacyLeft = 50;
sl@0: 			iLegacyRight = 50;
sl@0: 			}
sl@0: 		else if ( iChannelGains[ELeftCh].iGain > iChannelGains[ERightCh].iGain )
sl@0: 			{
sl@0: 			iLegacyGain = iChannelGains[ELeftCh].iGain;
sl@0: 			iLegacyLeft = static_cast<TUint>
sl@0: 				((100*iLegacyGain)/(iLegacyGain+iChannelGains[ERightCh].iGain));
sl@0: 			iLegacyRight = 100 - iLegacyLeft;
sl@0: 			//(not that accurate, but sufficient for now)
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			iLegacyGain = iChannelGains[ERightCh].iGain;
sl@0: 			iLegacyRight = static_cast<TUint>
sl@0: 				((100*iLegacyGain)/(iLegacyGain+iChannelGains[ELeftCh].iGain));
sl@0: 			iLegacyLeft = 100 - iLegacyRight;
sl@0: 			}
sl@0: 
sl@0: 		DP3(DLINFO,"New values :iLegacyGain %d, iLegacyLeft %d, iLegacyRight %d",
sl@0: 				iLegacyGain,iLegacyLeft,iLegacyRight);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		// our request completed succesfully, no need to update cached values
sl@0: 		// just print values in debug version
sl@0: 		#ifdef _DEBUG
sl@0: 		RArray<TAudioChannelGain> gains;
sl@0: 		TUint left;
sl@0: 		TUint right;
sl@0: 		TUint gain;
sl@0: 		aGain.GetGain(gains);
sl@0: 		ASSERT(gains.Count()==2);
sl@0: 		if ( iChannelGains[ELeftCh].iGain == iChannelGains[ERightCh].iGain )
sl@0: 			{
sl@0: 			gain = iChannelGains[ELeftCh].iGain;
sl@0: 			left = 50;
sl@0: 			right = 50;
sl@0: 			}
sl@0: 		else if ( iChannelGains[ELeftCh].iGain > iChannelGains[ERightCh].iGain )
sl@0: 			{
sl@0: 			gain = iChannelGains[ELeftCh].iGain;
sl@0: 			left = 
sl@0: 				static_cast<TUint>((100*gain)/(gain+iChannelGains[ERightCh].iGain));
sl@0: 			right = 100 - left;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			gain = iChannelGains[ERightCh].iGain;
sl@0: 			right = 
sl@0: 				static_cast<TUint>((100*gain)/(gain+iChannelGains[ELeftCh].iGain));
sl@0: 			left = 100 - right;
sl@0: 			}
sl@0: 		gains.Close();
sl@0: 		DP3(DLINFO,"KErrNone (gain %d, left %d, right %d)", gain,left,right);
sl@0: 		#endif
sl@0: 		}
sl@0: 
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioCodecObserver
sl@0: // CDevAudioControl::SampleRateSet
sl@0: // -----------------------------------------------------------------------------
sl@0: void CDevAudioControl::SampleRateSet(TInt aError)
sl@0: 	{
sl@0: 	if(aError==KErrNone)
sl@0: 		{
sl@0: 		//Review if we call SetConfig or is only the first time that we load the codec
sl@0: 		if (iDesiredSampleRate > 0)
sl@0: 			{
sl@0: 			iCurrentSampleRate = iDesiredSampleRate;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 	    {
sl@0:         iAdaptationObserver->NotifyError(aError);
sl@0: 	    }
sl@0:     iDesiredSampleRate = 0;
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioCodecObserver
sl@0: // CDevAudioControl::ModeSet
sl@0: // -----------------------------------------------------------------------------
sl@0: void CDevAudioControl::ModeSet(TInt aError)
sl@0: 	{
sl@0: 	if(aError==KErrNone)
sl@0: 		{
sl@0: 		//Review if we call SetConfig or is only the first time that we load the codec
sl@0: 		if (iDesiredMode != KNullUid)
sl@0: 			{
sl@0: 			iCurrentMode = iDesiredMode;
sl@0: 			}
sl@0: 		}
sl@0:     else
sl@0:         {
sl@0:         iAdaptationObserver->NotifyError(aError);
sl@0:         }
sl@0:     iDesiredMode = KNullUid;
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioCodecObserver
sl@0: // CDevAudioControl::GetSupportedSampleRatesComplete
sl@0: // -----------------------------------------------------------------------------
sl@0: void CDevAudioControl::GetSupportedSampleRatesComplete(TInt aError)
sl@0: 	{
sl@0: 	iSupportedRates.Reset();
sl@0: 	CompleteMessageCap(aError);
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioCodecObserver
sl@0: // CDevAudioControl::GetSupportedModesComplete
sl@0: // -----------------------------------------------------------------------------
sl@0: void CDevAudioControl::GetSupportedModesComplete(TInt aError)
sl@0: 	{
sl@0: 	iSupportedModes.Reset();
sl@0: 	CompleteMessageCap(aError);
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::CompleteMessageCap
sl@0: // -----------------------------------------------------------------------------
sl@0: void CDevAudioControl::CompleteMessageCap(TInt aError)
sl@0: 	{
sl@0: 	if (iOutstandingCallbacks > 1) //waiting until the 2 outstanding callbacks arrival.
sl@0: 		{
sl@0: 		iOutstandingCallbacks--;
sl@0: 		iError = aError; //keeping the error.
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		if (iError == KErrNone)
sl@0: 			{
sl@0: 			iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			iAdaptationObserver->AsynchronousOperationComplete(iError, ETrue);
sl@0: 			}
sl@0: 		iError = KErrNone;
sl@0: 		iOutstandingCallbacks = KMaxCallbacksExpected;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::SetToneData
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: TInt CDevAudioControl::SetToneData(TToneData& /*aToneData*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::SetToneData *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	DP0_RET(KErrNotSupported, "%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MAudioContextObserver
sl@0: // CDevAudio::ContextEvent
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::ContextEvent(TUid aEvent, TInt aError)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::ContextEvent *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0:     if(!(iAdaptationObserver->AdaptorControlsContext()))
sl@0:         {
sl@0:         iIgnoreAsyncOpComplete = ETrue;
sl@0:         }
sl@0:     
sl@0: 	if (aEvent == KUidA3FContextUpdateComplete)
sl@0: 		{
sl@0: 	    if(iIgnoreAsyncOpComplete)
sl@0: 			{
sl@0:             iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
sl@0: 		    iIgnoreAsyncOpComplete = EFalse;
sl@0:    	    	}
sl@0:         else
sl@0:             {
sl@0:             iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
sl@0:            	}
sl@0: 		}
sl@0: 	else if(aEvent == KUidA3FContextPreEmption)
sl@0: 		{
sl@0: 		//If we are in a normal pre-emption cycle, we should not be in a mid-state.
sl@0: 		__ASSERT_DEBUG(!iDevAudio->IsMidState(iDevAudio->iActiveState), Panic(EInvalidStateDuringPreemptionCycle));
sl@0: 		iIgnoreAsyncOpComplete = ETrue;
sl@0: 		iAdaptationObserver->PreemptionStartedCallbackReceived();
sl@0: 		}
sl@0: 	//In a clashing pre-emption cycle we must be in a commit cycle, so do nothing here - CDevCommonControl deals
sl@0: 	//with this case.
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // From class MCustomInterfaceSupportObserver
sl@0: // CDevAudio::CustomInterfaceRemoval
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::CustomInterfaceRemoval(TUid aUid, TAny* /*aPtr*/)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::CustomInterfaceRemoval *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	// TODO: Review this functionality
sl@0: 	iAdaptationObserver->InterfaceDeleted(aUid);
sl@0: 	DP_OUT();
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::ResolveSampleRate
sl@0: // ---------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::ResolveSampleRate(TInt aSampleRate, TInt& aSampleRateValue)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::ResolveSampleRate, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TInt err(KErrArgument);
sl@0: 
sl@0: 	for (TUint i=0; i<=KMaxSampleRateIndex; i++)
sl@0: 		{
sl@0: 		if(KRateTableLookup[i].iSampleRate == aSampleRate)
sl@0: 			{
sl@0: 			aSampleRateValue = KRateTableLookup[i].iSampleRateValue;
sl@0: 			err = KErrNone;
sl@0: 			break;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	//To avoid the value return a non desired value.
sl@0: 	if (err != KErrNone)
sl@0: 		{
sl@0: 		aSampleRateValue = 0;
sl@0: 		}
sl@0: 
sl@0: 	DP0_RET(err, "%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::ResolveMode
sl@0: // ---------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::ResolveMode(TUint aModeValue, TUid& aMode)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::ResolveMode *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TInt err(KErrArgument);
sl@0: 
sl@0: 	
sl@0: 	for (TInt i=0; i<=KMaxModeIndex; i++)
sl@0: 		{
sl@0: 		const TAudioModeTableEntry& entry = KModeTableLookup[i];
sl@0: 		if (entry.iAudioModeValue == aModeValue)
sl@0: 			{
sl@0: 			aMode = entry.iAudioMode;
sl@0: 			err = KErrNone;
sl@0: 			break;
sl@0: 			}
sl@0: 		}
sl@0: 	
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetModes
sl@0: // ---------------------------------------------------------------------------
sl@0: TUint CDevAudioControl::GetModes(const RArray<TUid>& aMode)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetModes *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	TUint result = 0;
sl@0: 	TInt count = aMode.Count();
sl@0: 
sl@0: 	for (TInt i=0; i<count; i++)
sl@0: 		{
sl@0: 		result |= GetMode(aMode[i]);
sl@0: 		}
sl@0: 	DP0_RET(result,"%d");
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetMode
sl@0: // ---------------------------------------------------------------------------
sl@0: TUint CDevAudioControl::GetMode(TUid aMode)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetMode *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	
sl@0: 	TUint result = 0;
sl@0: 	
sl@0: 	for (TInt e=0; e<=KMaxModeIndex; e++)
sl@0: 		{
sl@0: 		if(KModeTableLookup[e].iAudioMode == aMode)
sl@0: 			{
sl@0: 			result = KModeTableLookup[e].iAudioModeValue;
sl@0: 			break;
sl@0: 			}
sl@0: 		}
sl@0: 	DP0_RET(result,"%d");
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetSampleRates
sl@0: // ---------------------------------------------------------------------------
sl@0: TUint CDevAudioControl::GetSampleRates(const RArray<TInt>& aSampleRates)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetSampleRates *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	
sl@0: 	TUint result = 0;
sl@0: 	TInt count = aSampleRates.Count();
sl@0: 	
sl@0: 	for (TInt i=0; i<count; i++)
sl@0: 		{
sl@0: 		result |= GetSampleRate(aSampleRates[i]);
sl@0: 		}
sl@0: 	DP0_RET(result,"%d");
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetSampleRate
sl@0: // ---------------------------------------------------------------------------
sl@0: TUint CDevAudioControl::GetSampleRate(TInt aSampleRates)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetSampleRate *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	TUint result = 0;
sl@0: 	TInt position = 0;
sl@0: 	TInt lowerbound = 0;
sl@0: 	TInt upperbound = KMaxSampleRateIndex;
sl@0: 
sl@0: 	if ((aSampleRates < KRateTableLookup[lowerbound].iSampleRateValue) || (aSampleRates > KRateTableLookup[upperbound].iSampleRateValue)) 
sl@0: 		{
sl@0: 		//value request not found in the array.
sl@0: 		DP0_RET(result,"%d");
sl@0: 		}
sl@0: 
sl@0: 	//Binary Search
sl@0: 	position = ( lowerbound + upperbound) / 2;
sl@0: 
sl@0: 	while((KRateTableLookup[position].iSampleRateValue != aSampleRates) && (lowerbound <= upperbound))
sl@0: 		{
sl@0: 		if (KRateTableLookup[position].iSampleRateValue > aSampleRates)
sl@0: 			{
sl@0: 			upperbound = position - 1;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			lowerbound = position + 1;
sl@0: 			}
sl@0: 		position = (lowerbound + upperbound) / 2;
sl@0: 		}
sl@0: 
sl@0: 	result = KRateTableLookup[position].iSampleRate;
sl@0: 
sl@0: 	DP0_RET(result,"%d");
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::ProcessingFinishedReceived
sl@0: // ---------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::ProcessingFinishedReceived(TBool& /*aAyncOperation*/)
sl@0: 	{
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 	
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::ProcessingError
sl@0: // ---------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::ProcessingError(TBool& /*aAyncOperation*/)
sl@0:     {
sl@0:     return KErrNone;
sl@0:     }
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::RequestEmptyBuffers
sl@0: // ---------------------------------------------------------------------------	
sl@0: TInt CDevAudioControl::RequestEmptyBuffers()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::RequestEmptyBuffers *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 
sl@0: 	TInt err(KErrNotReady);
sl@0: 
sl@0: 	if(iDevAudio)
sl@0: 		{
sl@0: 		if(iDevAudio->iActiveState == EDevSoundAdaptorPaused_Primed)
sl@0: 			{
sl@0: 			err = iDevAudio->iAudioStream->Flush();
sl@0: 			}
sl@0: 		else if (iDevAudio->iActiveState == EDevSoundAdaptorActive_Active)
sl@0: 			{
sl@0: 			err = Pause();
sl@0: 			if(err == KErrNone)
sl@0: 				{
sl@0: 				iPauseResumeSequenceDueToEmptyBuffers = ETrue;
sl@0: 				}
sl@0: 			
sl@0: 			}
sl@0: 		}
sl@0: 	DP0_RET(err,"%d");
sl@0: 	};
sl@0: 
sl@0: void CDevAudioControl::Panic(TDevSoundAdaptorPanicCode aCode)
sl@0: 	{
sl@0: 	_LIT(KMMFDevSoundAdaptorPanicCategory, "DevSoundAdaptor");
sl@0: 	User::Panic(KMMFDevSoundAdaptorPanicCategory, aCode);
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::GetTimePlayed
sl@0: // ---------------------------------------------------------------------------
sl@0: TInt CDevAudioControl::GetTimePlayed(TTimeIntervalMicroSeconds& aTime)
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::GetTimePlayed *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	TInt err = iDevAudio->iAudioStream->GetStreamTime(aTime);
sl@0: 	DP0_RET(err,"%d");
sl@0: 	}
sl@0: 
sl@0: // ---------------------------------------------------------------------------
sl@0: // CDevAudioControl::Resume
sl@0: // ---------------------------------------------------------------------------
sl@0: TBool CDevAudioControl::Resume()
sl@0: 	{
sl@0: 	DP_CONTEXT(CDevAudioControl::Stop *CD1*, CtxDevSound, DPLOCAL);
sl@0: 	DP_IN();
sl@0: 	ASSERT(EFalse);
sl@0: 	DP0_RET(KErrNone, "%d");
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // CDevAudioControl::BufferErrorEvent
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: void CDevAudioControl::BufferErrorEvent()
sl@0: 	{
sl@0: 	ASSERT(EFalse); //This should never happen
sl@0: 	}
sl@0: // End of file