mmhais/a3facl/src/audiocontext/audiocontext.cpp
changeset 0 79dd3e2336a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmhais/a3facl/src/audiocontext/audiocontext.cpp	Fri Oct 08 19:40:43 2010 +0100
@@ -0,0 +1,559 @@
+//audiocontext.cpp
+
+// 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 <a3f/maudiostream.h>
+#include <a3f/maudiocodec.h>
+#include <a3f/maudiogaincontrol.h>
+#include <a3f/a3fbase.h>
+
+#include "audiocontext.h"
+#include "audioprocessingunit.h"
+#include "logicalaudiostream.h"
+#include "audiostreammanager.h"
+
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CAudioContext::CAudioContext() 
+	{
+	TRACE_CREATE();
+	DP_CONTEXT(CAudioContext::CAudioContext *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iInCommit = EFalse;
+	DP_OUT();
+	}
+	
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor
+// ---------------------------------------------------------------------------
+void CAudioContext::ConstructL()
+	{
+	DP_CONTEXT(CAudioContext::ConstructL *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	// Setup Multimedia Resource Control
+	User::LeaveIfError(iMMRC.Open(*this));
+	User::LeaveIfError(iCriticalSection.CreateLocal());
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// Symbian constructor
+// ---------------------------------------------------------------------------
+EXPORT_C  CAudioContext* CAudioContext::NewL()
+	{
+	DP_STATIC_CONTEXT(CAudioContext::NewL *CD0*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	CAudioContext* self = new(ELeave)CAudioContext();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	DP0_RET(self, "0x%x");
+	}
+	
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAudioContext::~CAudioContext()
+	{
+	DP_CONTEXT(CAudioContext::~CAudioContext *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iMMRC.Close();	
+	iAudioContextObservers.Close();
+	iAudioProcessingUnits.Close();
+	if (iActualChain)
+		{
+		iActualChain->Release();
+		};
+	iCriticalSection.Close();
+	DP_OUT();
+	}
+	
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::SetClientSettings
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::SetClientSettings(const TClientContextSettings& aSettings)
+	{
+	DP_CONTEXT(CAudioContext::SetClientSettings *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	iClientSettings = aSettings;
+	if( iContextId.Id() == 0 )
+		{
+		TUint64 id = iMMRC.LogOn(iClientSettings.iProcessId);
+		TAudioContextId temp(id);
+		iContextId = temp;
+		}
+	else
+		{
+		err = KErrAlreadyExists;
+		}
+	DP0_RET(err, "%d");
+	}
+
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::GetContextId
+// ---------------------------------------------------------------------------
+//
+TAudioContextId CAudioContext::ContextId() const 
+	{
+	DP_CONTEXT(CAudioContext::ContextId *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	return iContextId;
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::Commit
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::Commit()
+	{
+	DP_CONTEXT(CAudioContext::Commit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	iInCommit = ETrue;
+	
+	if (iClientSettings.iProcessId.Id() == 0)
+		{
+		DP0_RET(KErrNotReady, "%d");
+		}
+
+	err = iMMRC.SendResourceRequest(iActualChain, iDesiredChain, this);
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::CreateAudioStream
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::CreateAudioStream(MAudioStream *&aStream) 
+	{
+	DP_CONTEXT(CAudioContext::CreateAudioStream *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+
+	CAudioStreamManager* manager(NULL);
+
+	// Create desired logical chain
+	TRAP(err, manager = CAudioStreamManager::NewL(KUidAudioStream));
+	if(err == KErrNone)
+		{
+		aStream = static_cast<MAudioStream*>(manager);
+
+		// Use this as desired chain (this is the one that the client modify)
+		CLogicalAudioStream* logicalAudioStream = static_cast<CLogicalAudioStream*>(aStream);
+		iDesiredChain = static_cast<MLogicalChain*>(logicalAudioStream); 
+		logicalAudioStream->SetParentContext(*this);
+		if (iActualChain)
+			{
+			iActualChain->Release();
+			iActualChain=NULL;
+			}
+		TRAP(err, iActualChain = iDesiredChain->CloneL());
+		}
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::DeleteAudioStream
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::DeleteAudioStream(MAudioStream *&aStream)
+	{
+	DP_CONTEXT(CAudioContext::DeleteAudioStream *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	CAudioStreamManager* manager = static_cast<CAudioStreamManager*>(aStream);
+	delete manager;
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::CreateAudioProcessingUnit
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::CreateAudioProcessingUnit(TUid aTypeId, MAudioProcessingUnit *&aProcessingUnit)
+	{
+	DP_CONTEXT(CAudioContext::CreateAudioProcessingUnit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	TAudioComponentId unitInstance = GetAndSetInstanceID();
+	
+	CAudioProcessingUnit* pUnit=NULL;
+	TComponentParameters cParameters;
+	cParameters.iTypeUid = aTypeId;
+	cParameters.iInstanceId = unitInstance;
+	cParameters.iContextId = iContextId;
+	cParameters.iSettingsObserver = this;
+	
+	TRAP(err, pUnit = CAudioProcessingUnit::NewL(cParameters));
+	if (err==KErrNone)
+		{
+		aProcessingUnit = static_cast<MAudioProcessingUnit*>(pUnit);
+		err = iAudioProcessingUnits.Append(aProcessingUnit);
+		if(err!=KErrNone)
+			{
+			delete pUnit;
+			aProcessingUnit = NULL;
+			}
+		}
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::DeleteAudioProcessingUnit
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::DeleteAudioProcessingUnit(
+	MAudioProcessingUnit *&aProcessingUnit)
+	{
+	DP_CONTEXT(CAudioContext::DeleteAudioProcessingUnit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	CAudioProcessingUnit* cUnit = static_cast<CAudioProcessingUnit*>(aProcessingUnit);
+	TAudioComponentId param = aProcessingUnit->InstanceId();
+	TUint count= iAudioProcessingUnits.Count();
+		
+	for ( TUint i(0); i < count; i++ )
+		{
+		// find and delete component
+		if( iAudioProcessingUnits[i]->InstanceId() == param)
+			{
+			iAudioProcessingUnits.Remove(i);
+			delete cUnit;
+			break;
+			}
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::RegisterAudioContextObserver
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::RegisterAudioContextObserver(
+	MAudioContextObserver& aObserver)
+	{
+	DP_CONTEXT(CAudioContext::RegisterAudioContextObserver *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = iAudioContextObservers.Find(&aObserver);
+	if( err != KErrNotFound )
+		{
+		err = KErrAlreadyExists;
+		}
+	else
+		{
+		err = iAudioContextObservers.Append(&aObserver);
+		}
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::UnregisterAudioContextObserver
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::UnregisterAudioContextObserver(
+	MAudioContextObserver& aObserver)
+	{
+	DP_CONTEXT(CAudioContext::UnregisterAudioContextObserver *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	TInt idxOrErr = iAudioContextObservers.Find(&aObserver);
+	if( idxOrErr != KErrNotFound )
+		{
+		iAudioContextObservers.Remove(idxOrErr);
+		}
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::Interface
+// ---------------------------------------------------------------------------
+//
+TAny* CAudioContext::Interface(TUid aType)
+	{
+	DP_CONTEXT(CAudioContext::Interface *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TAny* interface = NULL;
+	if(aType == KUIdAudioResourceNotification)
+		{
+		#ifndef SYMBIAN_DISABLE_ARN
+		interface = static_cast<MA3FDevSoundAutoPauseResume*>(this);
+		#else
+		interface = NULL;
+		#endif
+		}
+	else
+		{
+		interface = NULL;
+		}
+	DP_OUT();
+	return interface;
+	}
+
+
+// ---------------------------------------------------------------------------
+// From class MAudioContext
+// CAudioContext::Reset
+// ---------------------------------------------------------------------------
+//
+TInt CAudioContext::Reset()
+	{
+	DP_CONTEXT(CAudioContext::Reset *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err = KErrNone;
+	if (iInCommit)
+		{
+		err = KErrNotReady;
+		}
+	iDesiredChain->ResetMessage();
+	iDesiredChain->CopySettings(*iActualChain);
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// From class MMultimediaResourceControlObserver
+// CAudioContext::ReceiveResourceResponse
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::ReceiveResourceResponse(MLogicalChain* aAppliedChain, TInt aError)
+	{
+	DP_CONTEXT(CAudioContext::ReceiveResourceResponse *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	
+	iCriticalSection.Wait();
+	iMsgVersion++;
+	iMMRC.ResetMessages();
+	iCriticalSection.Signal();
+	
+	if ( aError == KErrNone || iPreempted )
+		{
+		if ( iPreempted )
+			{
+			iPreempted = EFalse;
+			}
+		// Desired chain was commited succesfully
+		TInt err;
+		MLogicalChain* lc = NULL;
+		TRAP(err, lc = aAppliedChain->CloneL());
+		DP1(DLERR,"ECloneLeftWhenReceivingResourceResponse %d", err);
+		__ASSERT_DEBUG(err == KErrNone, Panic(ECloneLeftWhenReceivingResourceResponse));
+		if ( iActualChain )
+			{
+			iActualChain->Release();
+			}
+		iActualChain = lc;
+		}
+	else
+		{
+		iDesiredChain->CopySettings(*iActualChain);
+		}
+	iDesiredChain->ResetMessage();
+	ContextEventSignal(KUidA3FContextUpdateComplete, aError);
+	iInCommit = EFalse;
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// From class MMultimediaResourceControlObserver
+// CAudioContext::ReceiveResourceUpdate
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::ReceiveResourceUpdate(MLogicalChain* /*aMessage*/, TInt aError)
+	{
+	DP_CONTEXT(CAudioContext::ReceiveResourceUpdate *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	ContextEventSignal(KUidA3FContextCommitUpdate, aError);	
+	DP_OUT();
+	}
+
+
+// ---------------------------------------------------------------------------
+// From class MMultimediaResourceControlObserver
+// CAudioContext::ReceivePreemptionUpdate
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::ReceivePreemptionUpdate(MLogicalChain* /*aMessage*/, TInt aError)
+	{
+	DP_CONTEXT(CAudioContext::ReceivePreemptionUpdate *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	iPreempted = ETrue;
+	if(iInCommit)
+		{
+		// Send only one callback
+		ContextEventSignal(KUidA3FContextPreEmptedCommit, aError);
+		}
+	else
+		{
+		// Send two callbacks
+		ContextEventSignal(KUidA3FContextPreEmption, aError);
+		ContextEventSignal(KUidA3FContextPreEmptionUpdate, aError);
+		}
+	DP_OUT();
+	}
+
+
+// ---------------------------------------------------------------------------
+// From class MLogicalSettingObserver
+// CAudioContext::ReceiveComponentSettingsChange
+// ---------------------------------------------------------------------------
+void CAudioContext::ReceiveComponentSettingsChange(TUid /*aId*/, TMMRCMessageType aMessageType)
+	{
+	iDesiredChain->SetMessageType(aMessageType);
+	}
+
+// ---------------------------------------------------------------------------
+// Internals
+// CAudioContext::GetAndSetInstanceID
+// ---------------------------------------------------------------------------
+TAudioComponentId CAudioContext::GetAndSetInstanceID()
+	{
+	DP_CONTEXT(CAudioContext::GetAndSetInstanceID *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TUint id(1); // start ID count from 1
+	TAudioComponentId idComponent(1);
+	TUint count = iAudioProcessingUnits.Count();
+	if ( count < KMaxTUint )
+		{
+		id = ++count;
+		}
+	idComponent = id;
+	DP_OUT();
+	return idComponent;
+	}
+
+// ---------------------------------------------------------------------------
+// Internals
+// CAudioContext::ContextEventSignal
+// ---------------------------------------------------------------------------
+void CAudioContext::ContextEventSignal(TUid aEvent, TInt aError)
+	{
+	DP_CONTEXT(CAudioContext::ContextEventSignal *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TUint count = iAudioContextObservers.Count();
+	for ( TUint idx(0); idx < count; idx++ )
+		{
+		iAudioContextObservers[idx]->ContextEvent(aEvent, aError);
+		}
+	DP_OUT();
+	}
+
+// ---------------------------------------------------------------------------
+// CAudioContext::GetLogicalChain
+// ---------------------------------------------------------------------------
+EXPORT_C MLogicalChain* CAudioContext::GetLogicalChain(TInt aIndex)
+	{
+	DP_CONTEXT(CAudioContext::GetLogicalChain *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	MLogicalChain* logChain = NULL;
+	if (aIndex == 0)
+		{
+		logChain = iDesiredChain;
+		}
+	else
+		{
+		logChain = iActualChain;
+		}
+	DP_OUT();
+	return logChain;
+	}
+
+
+// ---------------------------------------------------------------------------
+// CAudioContext::RegisterAsClient
+// ---------------------------------------------------------------------------
+TInt CAudioContext::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData, MA3FDevSoundAutoPauseResumeObserver* aObserverPtr)
+	{
+	DP_CONTEXT(CAudioContext::RegisterAsClient *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	iObserverPtr = aObserverPtr;
+	err = iMMRC.RegisterAsClient(aEventType, aNotificationRegistrationData);
+	DP0_RET(err, "%d");
+	}
+
+// ---------------------------------------------------------------------------
+// CAudioContext::CancelRegisterAsClient
+// ---------------------------------------------------------------------------
+TInt CAudioContext::CancelRegisterAsClient(TUid aEventType)
+	{
+	DP_CONTEXT(CAudioContext::CancelRegisterAsClient *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	err = iMMRC.CancelRegisterAsClient(aEventType);
+	DP0_RET(err, "%d");
+	}
+	
+// ---------------------------------------------------------------------------
+// CAudioContext::WillResumePlay
+// ---------------------------------------------------------------------------
+TInt CAudioContext::WillResumePlay()
+	{
+	DP_CONTEXT(CAudioContext::WillResumePlay *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	err = iMMRC.WillResumePlay();
+	DP0_RET(err, "%d");
+	}
+	
+// ---------------------------------------------------------------------------
+// From class MMultimediaResourceControlObserver
+// CAudioContext::CanResume
+// ---------------------------------------------------------------------------
+//
+void CAudioContext::CanResume()
+	{
+	DP_CONTEXT(CAudioContext::CanResume *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	if(iObserverPtr)
+		{
+		iObserverPtr->NotifyResume();
+		}	
+	DP_OUT();
+	}
+
+void CAudioContext::Panic(TAudioContextPanicCodes aCode)
+	{
+	User::Panic(KAudioContextPanicCategory, aCode);
+	}
+	
+EXPORT_C TInt CAudioContext::MsgVersion()
+	{
+	return iMsgVersion;
+	}
+	
+EXPORT_C RCriticalSection& CAudioContext::CriticalSection()
+	{
+	return iCriticalSection;
+	}
+// End of file