diff -r 000000000000 -r b8ed18f6c07b devsound/a3fdevsound/src/devsoundadaptor/cdevaudio.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(iGlobalProperties->GetFourCCConvertor())); + + // The generic audio control is the only one receiving the callbacks at this moment + iCurrentAudioControl = static_cast(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(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(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(iDevToneControl); + err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl); + } + if ((err != KErrNone) && (err != KErrAlreadyExists)) + { + DeleteAudioProcessingUnits(); + } + } + else if (aMode == EMMFStateIdle) + { + // Unsure about this + iAudioContext->UnregisterAudioContextObserver(*iCurrentAudioControl); + iCurrentAudioControl = static_cast(iDevGenControl); + err = iAudioContext->RegisterAudioContextObserver(*iCurrentAudioControl); + } + else + { + iCurrentAudioControl = static_cast(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(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& 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& aSupportedDataTypes, RArray& aSupportedFormats) + { + DP_CONTEXT(CDevAudio::ConvertToFourCcL *CD1*, CtxDevSound, DPLOCAL); + DP_IN(); + + if(aSupportedFormats.Count() > 0) + { + TFourCC fourCC; + + for(TInt element=0; element(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(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(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(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