devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp
changeset 0 b8ed18f6c07b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp	Thu Oct 07 22:34:12 2010 +0100
@@ -0,0 +1,1109 @@
+// Copyright (c) 2006-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:
+//
+
+
+
+#include "cdevaudio.h"
+#include "cdevaudiocontrol.h"
+#include "cdevplaycontrol.h"
+#include "cdevrecordcontrol.h"
+#include "cdevtonecontrol.h"
+#include "cdevgencontrol.h"
+
+#include <a3f/audioprocessingunittypeuids.h>
+#include <a3f/devsoundadaptationinfo.h>
+#include <a3f/a3ffourcclookup.h>
+#include <a3f/audiocontextfactory.h>
+#include <a3f/maudioprocessingunit.h>
+#include <a3f/maudiocontext.h>
+#include <a3f/mcontexteffectiveclient.h>
+#include <a3f/maudiostream.h>
+#include <a3f/maudiocodec.h>
+#include <a3f/maudiogaincontrol.h>
+#include <a3f/mbuffersource.h>
+#include <a3f/mbuffersink.h>
+
+#include "mglobalproperties.h"
+
+const TInt KMidWayBalance = 50; // 50%
+const TInt KMaxBalance = 100; // 100%
+const TInt KLeftChannel = 0;
+const TInt KRightChannel = 1;
+
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CDevAudio::CDevAudio(MDevSoundAdaptationObserver& aAdaptationObserver)
+	: iAdaptationObserver(aAdaptationObserver), iMode(EMMFStateIdle), 
+	iActiveState(EDevSoundAdaptorCreated_Uninitialised),
+	iActiveStreamState(EUninitialized)
+	{
+	TRACE_CREATE();
+	DP_CONTEXT(CDevAudio::CDevAudio *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+		
+	iDevSoundPlayBalance[KLeftChannel] = iDevSoundPlayBalance[KRightChannel] = KMidWayBalance;
+	iDevSoundRecordBalance[KLeftChannel] = iDevSoundRecordBalance[KRightChannel] = KMidWayBalance;
+
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CDevAudio::~CDevAudio()
+	{
+	DP_CONTEXT(CDevAudio::~CDevAudio *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	delete iAdaptationInfo;
+	
+	iSupportedInputFormats.Close();
+	iSupportedOutputFormats.Close();
+
+	// This part is fine at the destructor
+	// All this is syncronous
+	if ( iAudioContext )
+		{
+		if ( iGainControl )
+			{
+			iAudioContext->DeleteAudioProcessingUnit(iGainControl);
+			}
+		if ( iAudioSink )
+			{
+			iAudioContext->DeleteAudioProcessingUnit(iAudioSink);
+			}
+		if ( iAudioCodec )
+			{
+			iAudioContext->DeleteAudioProcessingUnit(iAudioCodec);
+			}
+		if ( iAudioSource )
+			{
+			iAudioContext->DeleteAudioProcessingUnit(iAudioSource);
+			}
+		if ( iAudioStream )
+			{
+			iAudioContext->DeleteAudioStream(iAudioStream);
+			}
+		}
+
+	iAudioContextFactory->DeleteAudioContext(iAudioContext);
+	
+	if ( iAudioContextFactory )
+		{
+		delete iAudioContextFactory;
+		}
+
+	if ( iDevPlayControl )
+		{
+		delete iDevPlayControl;
+		}
+	if ( iDevRecordControl )
+		{
+		delete iDevRecordControl;
+		}
+	if ( iDevToneControl )
+		{
+		delete iDevToneControl;
+		}
+	if ( iDevGenControl )
+		{
+		delete iDevGenControl;
+		}
+	
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CDevAudio* CDevAudio::NewL(MDevSoundAdaptationObserver& aAdaptationObserver, 
+									MGlobalProperties& aGlobalProperties)
+	{
+	DP_STATIC_CONTEXT(CDevAudio::NewL *CD0*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	CDevAudio* self = new (ELeave) CDevAudio(aAdaptationObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL(aGlobalProperties);
+	CleanupStack::Pop(self);
+	DP0_RET(self, "0x%x");
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::ConstructL(MGlobalProperties& aGlobalProperties)
+	{
+	DP_CONTEXT(CDevAudio::ConstructL *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	iGlobalProperties = &aGlobalProperties;
+
+	iAudioContextFactory = CAudioContextFactory::NewL();
+	
+	User::LeaveIfError(iAudioContextFactory->CreateAudioContext(iAudioContext));
+
+	User::LeaveIfError(iAudioContext->CreateAudioStream(iAudioStream));
+	
+	User::LeaveIfError(iAudioContext->CreateAudioProcessingUnit(KUidAudioGainControl, iGainControl));
+	User::LeaveIfError(iAudioStream->AddGainControl(iGainControl));
+
+	iDevPlayControl = CDevPlayControl::NewL(this, iAdaptationObserver);
+	iDevRecordControl = CDevRecordControl::NewL(this, iAdaptationObserver);
+	iDevToneControl = CDevToneControl::NewL(this, iAdaptationObserver);
+	iDevGenControl = CDevGenControl::NewL(this, iAdaptationObserver);
+	
+	iAdaptationInfo = CA3FDevSoundAdaptationInfo::NewL(*this, const_cast<CFourCCConvertor&>(iGlobalProperties->GetFourCCConvertor()));
+
+	// The generic audio control is the only one receiving the callbacks at this moment
+	iCurrentAudioControl = static_cast<CDevAudioControl*>(iDevGenControl);
+	TInt err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl);
+	if ((err != KErrNone) && (err != KErrAlreadyExists))
+		{
+		User::Leave(err);
+		}
+	DP_OUT();
+	}
+	
+// -----------------------------------------------------------------------------
+// CDevAudio::PostOpen
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::PostOpen()
+	{
+	DP_CONTEXT(CDevAudio::PostOpen *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	ASSERT(iPreOpenState==EPreOpenStateIdle);
+	TInt err = KErrNone;
+	
+	if(iPreOpenState == EPreOpenStateIdle)
+		{
+		err = iAdaptationInfo->RequestMaxGain(KUidAudioDecoder);
+		if (err == KErrNone)
+			{
+			iPreOpenState = EPreOpenStateRequestingMaxVolume;
+			}
+		}
+	
+	DP0_RET(err, "%d");
+	}
+	
+
+TBool CDevAudio::IsResumeSupported()
+	{
+	DP_CONTEXT(CDevAudio::IsResumeSupported *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	TUid codecType(KNullUid);
+	if(iMode == EMMFStatePlaying || iMode == EMMFStateTonePlaying)
+		{
+		codecType = KUidAudioDecoder;
+		}
+	else if (iMode == EMMFStateRecording)
+		{
+		codecType = KUidAudioEncoder;
+		}
+	TBool supported = iAdaptationInfo->IsResumeSupported(codecType, iFormat);
+
+	DP0_RET(supported, "%d");
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::RequestMaxGainComplete
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::RequestMaxGainComplete (TUid __DEBUG_ONLY(aCodecType), TInt aError, TInt aResult)
+	{
+	DP_CONTEXT(CDevAudio::RequestMaxGainComplete *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	ASSERT(iPreOpenState==EPreOpenStateRequestingMaxVolume && aCodecType==KUidAudioDecoder||
+			iPreOpenState==EPreOpenStateRequestingMaxGain && aCodecType==KUidAudioEncoder);
+
+	TInt err = aError;
+	TBool asyncComplete = EFalse;
+	
+	if (err == KErrNone)
+		{
+		if (iPreOpenState==EPreOpenStateRequestingMaxVolume)
+			{
+			iDevSoundMaxVolume = aResult;
+						
+			err = SetDevSoundVolume((iDevSoundMaxVolume+1)/2, asyncComplete);
+
+			__ASSERT_DEBUG(asyncComplete==EFalse, User::Invariant());
+			
+			if(err == KErrNone)
+				{
+				// first request - so request max gain
+				err = iAdaptationInfo->RequestMaxGain(KUidAudioEncoder);
+				if (err == KErrNone)
+					{
+					iPreOpenState = EPreOpenStateRequestingMaxGain;
+					}
+				}
+			}
+		else if(iPreOpenState==EPreOpenStateRequestingMaxGain)
+			{
+			iDevSoundMaxGain = aResult;
+			
+			err = SetDevSoundGain((iDevSoundMaxGain+1)/2, asyncComplete);
+
+			__ASSERT_DEBUG(asyncComplete==EFalse, User::Invariant());
+			
+			if(err == KErrNone)
+				{
+				// second request - complete whatever - Ready for Formats
+				err = iAdaptationInfo->RequestSupportedFormats(KUidAudioDecoder, iSupportedInputFormats);
+				if (err == KErrNone)
+					{
+					iPreOpenState = EPreOpenStateRequestingInputFormats;
+					}
+				}
+			}
+		}
+
+	if (err!=KErrNone)
+		{
+		iPreOpenState = EPreOpenStateIdle;
+		iAdaptationObserver.AsynchronousOperationComplete(err, ETrue);
+		}
+	
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::RequestSupportedFormatsComplete
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::RequestSupportedFormatsComplete(TUid __DEBUG_ONLY(aCodecType), TInt aError)
+	{
+	DP_CONTEXT(CDevAudio::RequestSupportedFormatsComplete *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	ASSERT(iPreOpenState==EPreOpenStateRequestingInputFormats && aCodecType==KUidAudioDecoder||
+			iPreOpenState==EPreOpenStateRequestingOutputFormats && aCodecType==KUidAudioEncoder);
+
+	TInt err = aError;
+
+	if (err == KErrNone)
+		{
+		if (iPreOpenState==EPreOpenStateRequestingInputFormats)
+			{
+			// first request - so request output formats
+			err = iAdaptationInfo->RequestSupportedFormats(KUidAudioEncoder, iSupportedOutputFormats);
+			if (err == KErrNone)
+				{
+				iPreOpenState = EPreOpenStateRequestingOutputFormats;
+				}
+			}
+		else
+			{
+			ASSERT(iPreOpenState==EPreOpenStateRequestingOutputFormats);
+			// second request - complete whatever
+			iPreOpenState = EPreOpenStateIdle;
+			iAdaptationObserver.AsynchronousOperationComplete(aError, ETrue);
+			}
+		}
+
+	if (err!=KErrNone)
+		{
+		iPreOpenState = EPreOpenStateIdle;
+		iAdaptationObserver.AsynchronousOperationComplete(err, ETrue);
+		}
+	DP_OUT();
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::Initialize
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::Initialize(TUid aFormat, TMMFState aMode)
+	{
+	DP_CONTEXT(CDevAudio::Initialize*CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+
+	if(iActiveState != EDevSoundAdaptorCreated_Uninitialised &&
+		iActiveState != EDevSoundAdaptorInitialised_Initialised && 
+		iActiveState != EDevSoundAdaptorInitialised_Idle &&
+		iActiveState != EDevSoundAdaptorUnitialised_Uninitialised )
+		{
+		DP0_RET(KErrNotReady, "%d");
+		}
+
+	// Reinitialization 
+	if (iActiveState == EDevSoundAdaptorInitialised_Initialised || 
+		iActiveState == EDevSoundAdaptorInitialised_Idle)
+		{
+		iReinitializing = ETrue;
+		iTargetFormat = aFormat;
+		iTargetMode = aMode;
+		if(iActiveState == EDevSoundAdaptorInitialised_Idle)
+			{
+			err = iAudioStream->Unload();
+			if(err == KErrNone)
+				{
+				err = CommitAudioContext();
+				}
+			if(err == KErrNone)
+				{
+				iActiveState = EDevSoundAdaptorUnloading;
+				}
+			}
+		else
+			{
+			err = iCurrentAudioControl->Uninitialize();
+			}
+		DP0_RET(err, "%d");
+		}
+
+	// Redo partial initialization after pre-emption clash event in
+	// EDevSoundAdaptorRemovingProcessingUnits state
+	if (iActiveState == EDevSoundAdaptorUnitialised_Uninitialised &&
+			iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
+		{
+		err = iCurrentAudioControl->RemoveProcessingUnits();
+		DP0_RET(err, "%d");
+		}
+
+	// Delete pUnits if already created
+	if (iAudioSource)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioSource);
+		iAudioSource = NULL;
+		}
+
+	if (iAudioSink)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioSink);
+		iAudioSink = NULL;
+		}
+
+	if (iAudioCodec)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioCodec);
+		iAudioCodec = NULL;
+		}
+
+	//	Create pUnits and select proper DevSound Adaptor Helper
+	if (aMode == EMMFStatePlaying)
+		{
+		// create correct type sink&source&codec
+		err = CreateAudioProcessingUnits(KUidMmfBufferSource, KUidAudioDeviceSink, KUidAudioDecoder);
+		if (err == KErrNone)
+			{
+			// Now just the playcontrol should receive the only one receiving events from 
+			// AudioContext
+			iAudioContext->UnregisterAudioContextObserver(*iCurrentAudioControl);
+			iCurrentAudioControl = static_cast<CDevAudioControl*>(iDevPlayControl);
+			err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl);
+			}
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			DeleteAudioProcessingUnits();
+			}
+		}
+		
+	else if (aMode == EMMFStateRecording)
+		{
+		// create correct type sink&source&codec
+		err = CreateAudioProcessingUnits(KUidAudioDeviceSource, KUidMmfBufferSink, KUidAudioEncoder);
+		if (err == KErrNone)
+			{
+			iAudioContext->UnregisterAudioContextObserver(*iCurrentAudioControl);
+			iCurrentAudioControl = static_cast<CDevAudioControl*>(iDevRecordControl);
+			err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl);
+			}
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			DeleteAudioProcessingUnits();
+			}
+		}
+	else if (aMode == EMMFStateTonePlaying)
+		{
+		// create correct type sink&source&codec
+		err = CreateAudioProcessingUnits(KUidMmfBufferSource, KUidAudioDeviceSink, KUidAudioDecoder);
+		if (err == KErrNone)
+			{
+			iAudioContext->UnregisterAudioContextObserver(*iCurrentAudioControl);
+			iCurrentAudioControl =  static_cast<CDevAudioControl*>(iDevToneControl);
+			err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl);
+			}
+	if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			DeleteAudioProcessingUnits();
+			}
+		}
+	else if (aMode == EMMFStateIdle)
+		{
+		// Unsure about this
+		iAudioContext->UnregisterAudioContextObserver(*iCurrentAudioControl);
+		iCurrentAudioControl =  static_cast<CDevAudioControl*>(iDevGenControl);
+		err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl);
+		}
+	else
+		{
+		iCurrentAudioControl = static_cast<CDevAudioControl*>(iDevGenControl);
+		err = KErrNotSupported;
+		}
+
+	if (err == KErrNone)
+		{
+		err = iCurrentAudioControl->Initialize(aFormat);	
+		}
+	
+	if(err == KErrNone)
+		{
+		iMode = aMode;
+		iFormat = aFormat;
+		}
+
+	DP0_RET(err, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::CancelInitialize
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::CancelInitialize()
+	{
+	DP_CONTEXT(CDevAudio::CancelInitialize *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+
+	// Redo partial cancelling of initialization after pre-emption clash event in
+	// EDevSoundAdaptorRemovingProcessingUnits state.
+	if (iActiveState == EDevSoundAdaptorUnitialised_Uninitialised &&
+			iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
+		{
+		err = iCurrentAudioControl->RemoveProcessingUnits();
+		DP0_RET(err, "%d");
+		}
+	else if(iActiveState != EDevSoundAdaptorInitialised_Initialised)
+		{
+		DP0_RET(KErrNotReady, "%d");
+		}
+
+	err = iCurrentAudioControl->Uninitialize();
+	
+	DP0_RET(err, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::GetAudioControl
+// -----------------------------------------------------------------------------
+//
+CDevAudioControl* CDevAudio::GetAudioControl()
+	{
+	DP_CONTEXT(CDevAudio::GetAudioControl *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	return iCurrentAudioControl;
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetPrioritySettings
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
+	{
+	DP_CONTEXT(CDevAudio::SetPrioritySettings *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iPrioritySettings.iPriority = aPrioritySettings.iPriority;
+	iPrioritySettings.iPref = aPrioritySettings.iPref;
+	iPriorityFlag = ETrue;
+	DP2(DLINFO, "Priority = 0x%x Preference = 0x%x", iPrioritySettings.iPriority,iPrioritySettings.iPref);
+	DP0_RET(0, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::GetPrioritySettings
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::GetPrioritySettings(TAudioTypeSettings& aPrioritySettings)
+	{
+	aPrioritySettings = iPrioritySettings;
+	}
+// -----------------------------------------------------------------------------
+// CDevAudio::IsPrioritySet
+// -----------------------------------------------------------------------------
+//
+TBool CDevAudio::IsPrioritySet()
+	{
+	return iPriorityFlag;
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetClientConfig
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetClientConfig(const TProcessId& aProcessId)
+	{
+	DP_CONTEXT(CDevAudio::SetClientConfig *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	// TODO: Check if the TClientContextSettings atributte go back since 
+	// if not there is no way to send the vendor id
+	TClientContextSettings context;
+	context.iProcessId = aProcessId;
+	TInt err = iAudioContext->SetClientSettings(context);
+	if (err != KErrNone)
+		{
+		DP1(DLERR, "Error %d setting client context!",err);
+		}
+	DP0_RET(err, "%d");
+	}
+
+TInt CDevAudio::SetClientConfig(const TProcessId& aActualProcessId, const TProcessId& aProcessId)
+	{
+	DP_CONTEXT(CDevAudio::SetClientConfig *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	MContextSetEffectiveClient* setEffectiveClient
+        = static_cast<MContextSetEffectiveClient*>(iAudioContext->Interface(KSetClientInfoUid));
+	
+	TInt err;
+	
+	if (!setEffectiveClient)
+	    {
+        DP0(DLINFO, "MContextSetEffectiveClient not supported, revert to old behaviour of just passing actual client info");
+        err = SetClientConfig(aActualProcessId);
+	    }
+	else
+	    {
+        TClientContextSettings context;
+        context.iProcessId = aProcessId;
+        err = iAudioContext->SetClientSettings(context);
+        if (err != KErrNone)
+            {
+            DP1(DLERR, "Error %d setting client context!",err);
+            }
+        if (!err)
+            {
+            err = setEffectiveClient->SetEffectiveClientInfo(aActualProcessId);
+            if (err != KErrNone)
+                {
+                DP1(DLERR, "Error %d setting effective client context!",err);
+                }
+            }
+	    }
+
+	DP0_RET(err, "%d");
+	}
+
+
+void CDevAudio::ContextEvent(TUid /*aEvent*/, TInt /*aError*/)
+	{
+	DP_CONTEXT(CDevAudio::ContextEvent *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::ActiveState
+// -----------------------------------------------------------------------------
+//
+TDevSoundAdaptorState CDevAudio::ActiveState() const
+	{
+	DP_CONTEXT(CDevAudio::ActiveState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP0_RET(iActiveState, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::ActiveState
+// -----------------------------------------------------------------------------
+//
+TDevSoundAdaptorState CDevAudio::PreviousState() const
+	{
+	DP_CONTEXT(CDevAudio::PreviousState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP0_RET(iPreviousState, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetActiveState
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::SetActiveState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::SetActiveState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iActiveState = aAdaptorState;
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetPreviousState
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::SetPreviousState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::SetPreviousState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iPreviousState = aAdaptorState;
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetDevSoundVolume
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetDevSoundVolume(TInt aVolume, TBool& aAsyncComplete)
+	{
+	DP_CONTEXT(CDevAudio::SetDevSoundVolume *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	// Values are clipped between 0 and MaxGain. 
+	// because MAudioGainControl expects this to be done
+	TInt volume = aVolume;
+	if (volume < 0)
+		{
+		volume = 0;
+		}
+	else if (volume > iDevSoundMaxVolume)
+		{
+		volume = iDevSoundMaxVolume;
+		}
+	iDevSoundVolume = volume;
+	
+	TInt error = SetGainAndBalance(EFalse, aAsyncComplete);
+
+	DP0_RET(error, "%d");
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetDevSoundGain
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetDevSoundGain(TInt aGain, TBool& aAsyncComplete)
+	{
+	DP_CONTEXT(CDevAudio::SetDevSoundGain *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	// Values are clipped between 0 and MaxGain. 
+	// because MAudioGainControl expects this to be done
+	TInt gain = aGain;
+	if (gain < 0)
+		{
+		gain = 0;
+		}
+	else if (gain > iDevSoundMaxGain)
+		{
+		gain = iDevSoundMaxGain;
+		}
+	iDevSoundGain = gain;
+
+	TInt error = SetGainAndBalance(EFalse, aAsyncComplete);
+
+	DP0_RET(error, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetDevSoundPlayBalance
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetDevSoundPlayBalance(TInt aLeftBalance, TInt aRightBalance, TBool& aAsyncComplete)
+	{
+	DP_CONTEXT(CDevAudio::SetDevSoundPlayBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	// Clipping values
+	TInt left = aLeftBalance;
+	if (left < 0)
+		{
+		left = 0;
+		}
+	else if (left > KMaxBalance)
+		{
+		left = KMaxBalance;
+		}
+	TInt right = aRightBalance;
+	if (right < 0)
+		{
+		right = 0;
+		}
+	else if (right > KMaxBalance)
+		{
+		right = KMaxBalance;
+		}
+	iDevSoundPlayBalance[KLeftChannel] = left;
+	iDevSoundPlayBalance[KRightChannel] = right;
+
+	TInt error = SetGainAndBalance(EFalse, aAsyncComplete);
+
+	DP0_RET(error, "%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetDevSoundRecordBalance
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetDevSoundRecordBalance(TInt aLeftBalance, TInt aRightBalance, TBool& aAsyncComplete)
+	{
+	DP_CONTEXT(CDevAudio::SetDevSoundRecordBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	// Clipping values	
+	TInt left = aLeftBalance;
+	if (left < 0)
+		{
+		left = 0;
+		}
+	else if (left > KMaxBalance)
+		{
+		left = KMaxBalance;
+		}
+	TInt right = aRightBalance;
+	if (right < 0)
+		{
+		right = 0;
+		}
+	else if (right > KMaxBalance)
+		{
+		right = KMaxBalance;
+		}
+	iDevSoundRecordBalance[KLeftChannel] = left;
+	iDevSoundRecordBalance[KRightChannel] = right;
+
+	TInt error = SetGainAndBalance(EFalse, aAsyncComplete);
+
+	DP0_RET(error, "%d");
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::SetVolumeRamp
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+	{
+	DP_CONTEXT(CDevAudioControl::SetVolumeRamp *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	iRampDuration = aRampDuration;
+	
+	DP0_RET(KErrNone,"%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::RequestGainAndBalance
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::RequestGainAndBalance(CDevAudioControl* aCallingControl)
+	{
+	DP_CONTEXT(CDevAudio::RequestGainAndBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	TInt error = KErrNone;
+	if (aCallingControl != iCurrentAudioControl)
+		{
+		error = KErrNotReady;
+		}
+	else
+		{
+		TBool dummy;
+		error = SetGainAndBalance(ETrue, dummy);
+		}
+	DP0_RET(error, "%d");
+	}
+	
+// -----------------------------------------------------------------------------
+// CDevAudio::SetGainAndBalance
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::SetGainAndBalance(TBool aBecomingActive, TBool& aAsyncComplete)
+	{
+	DP_CONTEXT(CDevAudio::SetGainAndBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	TInt error = KErrNone;
+	aAsyncComplete = EFalse; // let's assume this - makes logic easier below
+	// Apply cached settings. 
+	// If aBecomingActive is true it indicates this call is doing before the MAudioStream::Activate() transition, 
+	// so if required will apply volume ramp and won't itself generate a Commit() call. 
+	// Otherwise, when Active, the calls made here will generate a Commit() 
+	// and aAsyncComplete is returned true unless the SetGain() call fails
+	if (aBecomingActive || iActiveState == EDevSoundAdaptorActive_Active) 
+		{
+		if (iCurrentAudioControl==iDevRecordControl)
+			{
+			// TODO assumes we are not mid Commit cycle
+			// we are recing, need to change current volume at A3F layer
+			error = iCurrentAudioControl->SetGains(iDevSoundGain, iDevSoundMaxGain, iDevSoundRecordBalance, 0, aBecomingActive);
+			if (error==KErrNone)
+				{
+				aAsyncComplete = ETrue;
+				}
+			}
+		else if (iCurrentAudioControl==iDevPlayControl || iCurrentAudioControl==iDevToneControl)
+			{
+			// TODO assumes we are not mid Commit cycle
+			// we are playing, need to change current volume at A3F layer
+			error = iCurrentAudioControl->SetGains(iDevSoundVolume, iDevSoundMaxVolume, iDevSoundPlayBalance, iRampDuration, aBecomingActive);
+			if (error==KErrNone)
+				{
+				aAsyncComplete = ETrue;
+				}
+			}
+		
+		} 
+
+		
+	DP0_RET(error, "%d");	
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::GetDevSoundPlayBalance
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::GetDevSoundPlayBalance(TInt& aLeftBalance, TInt& aRightBalance)
+	{
+	DP_CONTEXT(CDevAudio::GetDevSoundPlayBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	aLeftBalance = iDevSoundPlayBalance[KLeftChannel];
+	aRightBalance = iDevSoundPlayBalance[KRightChannel];
+	DP_OUT();
+	}
+	
+
+// -----------------------------------------------------------------------------
+// CDevAudio::GetDevSoundRecordBalance
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::GetDevSoundRecordBalance(TInt& aLeftBalance, TInt& aRightBalance)
+	{
+	DP_CONTEXT(CDevAudio::GetDevSoundRecordBalance *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	aLeftBalance = iDevSoundRecordBalance[KLeftChannel];
+	aRightBalance = iDevSoundRecordBalance[KRightChannel];
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::DevSoundSupportedDataTypesL
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::DevSoundSupportedDataTypesL(RArray<TFourCC>& aSupportedDataTypes, TUint aDataType)
+	{
+	DP_CONTEXT(CDevAudio::DevSoundSupportedDataTypesL *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	//Clear any existing data
+	aSupportedDataTypes.Reset();
+	
+	if(aDataType == KDataForPlay)
+		{
+		ConvertToFourCcL(aSupportedDataTypes, iSupportedInputFormats);
+		}
+	else if(aDataType == KDataForRecord)
+		{
+		ConvertToFourCcL(aSupportedDataTypes, iSupportedOutputFormats);
+		}
+	
+	DP_OUT();
+	}
+	
+// -----------------------------------------------------------------------------
+// CDevAudio::ConvertToFourCcL
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::ConvertToFourCcL(RArray<TFourCC>& aSupportedDataTypes, RArray<TUid>& aSupportedFormats)
+	{
+	DP_CONTEXT(CDevAudio::ConvertToFourCcL *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	if(aSupportedFormats.Count() > 0)
+		{
+		TFourCC fourCC;
+		
+		for(TInt element=0; element<aSupportedFormats.Count(); element++)
+			{		
+			User::LeaveIfError(const_cast<CFourCCConvertor&>(iGlobalProperties->GetFourCCConvertor()).FormatToFourCC(aSupportedFormats[element],fourCC));
+			aSupportedDataTypes.AppendL(fourCC);	
+			}
+		}
+	DP_OUT();
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::CreateAudioProcessingUnits
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::CreateAudioProcessingUnits(TUid aSource, TUid aSink, TUid aCodec)
+	{
+	DP_CONTEXT(CDevAudio::CreateAudioProcessingUnits *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = iAudioContext->CreateAudioProcessingUnit(aSource, iAudioSource);
+	if(err != KErrNone)
+		{
+		DP0_RET(err,"Audio source creation failed!");
+		}
+	err = iAudioContext->CreateAudioProcessingUnit(aSink, iAudioSink);
+	if(err != KErrNone)
+		{
+		DP0_RET(err,"Audio sink creation failed!");
+		}
+	err = iAudioContext->CreateAudioProcessingUnit(aCodec, iAudioCodec);
+	if(err != KErrNone)
+		{
+		DP0_RET(err,"Audio codec creation failed!");
+		}
+
+	DP0_RET(err,"");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevAudio::DeleteAudioProcessingUnits
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::DeleteAudioProcessingUnits()
+	{
+	DP_CONTEXT(CDevAudio::DeleteAudioProcessingUnits *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	if (iAudioSource)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioSource);
+		iAudioSource = NULL;
+		}
+	if (iAudioSink)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioSink);
+		iAudioSink = NULL;
+		}
+	if (iAudioCodec)
+		{
+		iAudioContext->DeleteAudioProcessingUnit(iAudioCodec);
+		iAudioCodec = NULL;
+		}
+	DP_OUT();
+	}
+
+TInt CDevAudio::CommitAudioContext()
+	{
+	DP_CONTEXT(CDevAudio::CommitAudioContext *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	//If we are in mid state then Panic as DevSound server-side session (CMMFDevSoundSession) is not blocking properly
+	__ASSERT_DEBUG(!IsMidState(iActiveState), Panic(EValidStateBeforeCommit));
+
+	TInt err = KErrNone;
+	iPreviousState = iActiveState;
+	err = iAudioContext->Commit();
+
+	DP0_RET(err,"%d");
+	}
+
+TBool CDevAudio::IsMidState(TDevSoundAdaptorState aAdaptorState)
+	{
+	DP_CONTEXT(CDevAudio::IsMidState *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	if (aAdaptorState == EDevSoundAdaptorRemovingProcessingUnits || aAdaptorState == EDevSoundAdaptorUninitialising ||
+			aAdaptorState == EDevSoundAdaptorInitialising || aAdaptorState == EDevSoundAdaptorLoading ||
+			aAdaptorState == EDevSoundAdaptorUnloading || aAdaptorState == EDevSoundAdaptorStopping ||
+			aAdaptorState == EDevSoundAdaptorActivating || aAdaptorState == EDevSoundAdaptorPausing)
+		{
+		DP0_RET(ETrue,"%d");
+		}
+	DP0_RET(EFalse,"%d");
+	}
+
+// -----------------------------------------------------------------------------
+// From MA3FDevSoundAutoPauseResume
+// CDevAudio::RegisterAsClient
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData)
+	{
+	DP_CONTEXT(CDevAudio::RegisterAsClient *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = KErrNotSupported;
+	MA3FDevSoundAutoPauseResume* iAPR =  static_cast<MA3FDevSoundAutoPauseResume*>(iAudioContext->Interface(KUIdAudioResourceNotification));
+	if(iAPR)
+		{
+		err = iAPR->RegisterAsClient(aEventType, aNotificationRegistrationData, this);
+		}
+	DP0_RET(err, "%d");	
+	}
+	
+
+// -----------------------------------------------------------------------------
+// CDevAudio::CancelRegisterAsClient
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::CancelRegisterAsClient(TUid aEventType)
+	{
+	DP_CONTEXT(CDevAudio::CancelRegisterAsClient *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = KErrNotSupported;
+	MA3FDevSoundAutoPauseResume* iAPR =  static_cast<MA3FDevSoundAutoPauseResume*>(iAudioContext->Interface(KUIdAudioResourceNotification));
+	if(iAPR)
+		{
+		err = iAPR->CancelRegisterAsClient(aEventType);
+		}
+	DP0_RET(err, "%d");	
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::WillResumePlay
+// -----------------------------------------------------------------------------
+//
+TInt CDevAudio::WillResumePlay()
+	{
+	DP_CONTEXT(CDevAudio::WillResumePlay *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = KErrNotSupported;
+	MA3FDevSoundAutoPauseResume* iAPR =  static_cast<MA3FDevSoundAutoPauseResume*>(iAudioContext->Interface(KUIdAudioResourceNotification));
+	if(iAPR)
+		{
+		err = iAPR->WillResumePlay();
+		}
+	DP0_RET(err, "%d");	
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevAudio::NotifyResume
+// -----------------------------------------------------------------------------
+//
+void CDevAudio::NotifyResume()
+	{
+	DP_CONTEXT(CDevAudio::NotifyResume *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iAdaptationObserver.CallbackFromAdaptorReceived(KCallbackAutoPauseResume, KErrNone);
+	DP_OUT();
+	}
+
+void CDevAudio::Panic(TMMFDevAudioPanicCodes aCode)
+	{
+	User::Panic(KMMFDevAudioPanicCategory, aCode);
+	}
+
+// End of file