devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp
changeset 0 40261b775718
child 12 b74061f7f3d2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,370 @@
+// 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 "cdevplaycontrol.h"
+
+#include <a3f/maudiocontext.h>
+#include <a3f/mbuffersource.h>
+#include <a3f/maudiocodec.h>
+#include <a3f/maudiogaincontrol.h>
+#include <a3f/audioprocessingunittypeuids.h>
+
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CDevPlayControl::CDevPlayControl()
+	{
+	TRACE_CREATE();
+	DP_CONTEXT(CDevPlayControl::CDevPlayControl *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::ConstructL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aAdaptationObserver)
+	{
+	DP_CONTEXT(CDevPlayControl::ConstructL *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	CDevAudioControl::ConstructL(aDevAudio, aAdaptationObserver);
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// Symbian constructor
+// -----------------------------------------------------------------------------
+//
+CDevPlayControl* CDevPlayControl::NewL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aDevSoundObserver)
+	{
+	DP_STATIC_CONTEXT(CDevPlayControl::NewL *CD0*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	CDevPlayControl* self = new (ELeave) CDevPlayControl();
+	CleanupStack::PushL(self);
+	self->ConstructL(aDevAudio, aDevSoundObserver);
+	CleanupStack::Pop(self);
+	DP0_RET(self, "0x%x");
+	}
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CDevPlayControl::~CDevPlayControl()
+	{
+	DP_CONTEXT(CDevPlayControl::~CDevPlayControl *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::Initialize
+// -----------------------------------------------------------------------------
+//
+TInt CDevPlayControl::Initialize(TUid aFormat)
+	{
+	DP_CONTEXT(CDevPlayControl::Initialize *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	ASSERT(iDevAudio->iAudioSource && iDevAudio->iAudioCodec && iGainControl);
+	TInt err(KErrNone);
+
+	err = iDevAudio->iAudioStream->AddSource(iDevAudio->iAudioSource);
+	if (err == KErrNone)
+		{
+		err = iDevAudio->iAudioStream->AddSink(iDevAudio->iAudioSink);
+		if (err == KErrNone)
+			{
+			err = iDevAudio->iAudioStream->AddAudioCodec(iDevAudio->iAudioCodec);
+			}
+		}
+	
+	if(err == KErrNone && iDevAudio->iActiveState == EDevSoundAdaptorCreated_Uninitialised)
+		{
+		// Register for notifications
+		// Note KErrAlreadyExist is not acceptable as an error, since it shouldn't occurr 
+		// It's mandatory unregister any observer when no more events are required
+		// Otherwise the notifications will be sent to all previously registered observer
+		// when reinitialising for different mode
+		err = iDevAudio->iAudioStream->RegisterAudioStreamObserver(*this);
+		if (err == KErrNone)
+			{
+			err = iGainControl->RegisterAudioGainControlObserver(*this);
+			if (err == KErrNone)
+				{
+				err = CacheAudioCodecIf();
+				if (err == KErrNone)
+					{
+					__ASSERT_ALWAYS (iAudioCodecIf,CDevAudioControl::Panic(EAudioCodecIsNull));
+					err = iAudioCodecIf->RegisterAudioCodecObserver(*this);
+					if(err == KErrNone)
+						{
+						err = iAudioCodecIf->SetFormat(aFormat);
+						if (err == KErrNone)
+							{
+							// Needed to get ProcessingUnitError notification 
+							err = iDevAudio->iAudioCodec->RegisterProcessingUnitObserver(*this);
+							}
+						}
+					}
+				}
+			}
+
+		if (err != KErrNone)
+			{
+			DP0(DLINFO,"Error while registering observers");
+			iDevAudio->iAudioStream->UnregisterAudioStreamObserver(*this);
+			iGainControl->UnregisterAudioGainControlObserver(*this);
+			if(iAudioCodecIf)
+				{
+				iAudioCodecIf->UnregisterAudioCodecObserver(*this);
+				iAudioCodecIf = NULL; // Not owned here: convenience pointer, so no need to delete
+				}
+			}
+
+		if (err == KErrNone)
+			{
+			err = iDevAudio->iAudioStream->Initialize();
+			if (err == KErrNone)
+				{
+				err = iDevAudio->iAudioContext->Commit();
+				if (err == KErrNone)
+					{
+					iDevAudio->iActiveState = EDevSoundAdaptorInitialising;
+					}
+				}
+			}
+		}
+	DP0_RET(err,"%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::ProcessInit
+// -----------------------------------------------------------------------------
+//
+TInt CDevPlayControl::ProcessInit()
+	{
+	DP_CONTEXT(CDevPlayControl::ProcessInit *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	PRF(PRF_ID, PRF_START, PRF_TIME, AA_DS_PlayInit, "");
+	PRF(PRF_ID, PRF_START, PRF_LOAD, AA_DS_Play, "");
+	TInt err(KErrNone);
+	
+	switch (iDevAudio->iActiveState)
+		{
+		case EDevSoundAdaptorInitialised_Initialised:
+			{
+			TAny* interface(NULL);
+			// get correct BufferSource interface of DevAudio::iAudioSource
+			interface = iDevAudio->iAudioSource->Interface(KUidMmfBufferSource);
+			
+			if (interface == NULL)
+				{
+				DP0_RET(KErrNotSupported, "Incorrect source type! %d");
+				}
+			else
+				{
+				iBufferSource = static_cast<MMMFBufferSource*>(interface);
+				iBufferSource->SetDataSupplier(*this);
+				if (iDevAudio->IsPrioritySet())
+					{
+					TAudioTypeSettings priority;
+					iDevAudio->GetPrioritySettings(priority);
+					err = iDevAudio->iAudioStream->SetAudioType(priority);
+					}				
+				}
+			if ( err == KErrNone)
+				{
+				err = iDevAudio->iAudioStream->Load();
+				}
+			if ( err == KErrNone)
+				{
+				err = iDevAudio->iAudioContext->Commit();
+				}
+			if(err == KErrNone)
+				{
+				iDevAudio->iActiveState = EDevSoundAdaptorLoading;
+				}
+			}
+			break;
+
+		case EDevSoundAdaptorPaused_Primed:
+		case EDevSoundAdaptorInitialised_Idle:
+			err = iDevAudio->RequestGainAndBalance(this);
+			if (err==KErrNone)
+				{
+				err = iDevAudio->iAudioStream->Activate();
+				}
+			if (err == KErrNone)
+				{
+				err = iDevAudio->iAudioContext->Commit();
+				}
+			if (err == KErrNone)
+				{
+				iDevAudio->iActiveState = EDevSoundAdaptorActivating;
+				}
+			break;
+		case EDevSoundAdaptorActive_Active:
+			// Deliberate fall through - set err=KErrNotReady for PlayInit when already active
+		default:
+			err = KErrNotReady;
+			break;
+		}
+
+	if(err == KErrNone)
+		{
+		iDevAudio->iStop = EFalse;
+		}
+	
+	DP0_RET(err,"%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::ProcessData
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::ProcessData()
+	{
+	DP_CONTEXT(CDevPlayControl::ProcessData *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	TInt err(KErrNone);
+	
+	if(!iDevAudio->iStop)
+		{
+		err = iBufferSource->BufferFilled(iBuffer);
+		if ( err != KErrNone)
+			{
+			iErrorCondition = err;
+			Stop();
+			}
+		}
+
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// From class MAudioDataSupplier
+// CDevPlayControl::BufferToBeFilled
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::BufferToBeFilled(MMMFBufferSource* aSource, CMMFBuffer* aBuffer)
+	{
+	DP_CONTEXT(CDevPlayControl::BufferToBeFilled *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	PRF(PRF_ID, PRF_STOP, PRF_TIME, AA_DS_PlayInit, "");
+	__ASSERT_ALWAYS(iBufferSource==aSource, CDevAudioControl::Panic(EBufferMismatch));
+	iAdaptationObserver->BufferToBeFilled(aBuffer);
+	iBuffer = aBuffer;
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// From class MAudioDataSupplier
+// CDevPlayControl::DiscardBuffers
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::DiscardBuffers(MMMFBufferSource* /*aSource*/)
+	{
+	DP_CONTEXT(CDevPlayControl::DiscardBuffers *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+
+	DP_OUT();
+	}
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::ProcessingFinished
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::ProcessingFinished(MAudioStream& /*aStream*/)
+	{
+	DP_CONTEXT(CDevPlayControl::ProcessingFinished *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	PRF(PRF_ID, PRF_STOP, PRF_LOAD, AA_DS_Play, "");
+	
+	if(iCallbackFromAdaptor == KCallbackNone)
+		{
+		iCallbackFromAdaptor = KCallbackProcessingFinished;
+		iAdaptationObserver->CallbackFromAdaptorReceived(iCallbackFromAdaptor, KErrNone);
+		}
+	else
+		{
+		// Multiple callbacks from adaptor
+		DP0(DLERR, "Multiple callbacks from adaptor");
+		}
+	DP_OUT();
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::ProcessingFinishedReceived
+// -----------------------------------------------------------------------------
+//
+TInt CDevPlayControl::ProcessingFinishedReceived(TBool& aAyncOperation)
+	{
+	DP_CONTEXT(CDevPlayControl::ProcessingFinishedReceived *CD1*, CtxDevSound, DPLOCAL);
+	DP_IN();
+	aAyncOperation = EFalse;
+	TInt err = iDevAudio->iAudioStream->Stop();
+	if ( err == KErrNone)
+		{
+		err = iDevAudio->iAudioContext->Commit();
+		if(err == KErrNone)
+			{
+			iDevAudio->iActiveState = EDevSoundAdaptorStopping;
+			aAyncOperation = ETrue;
+			}
+		}
+	// Something was wrong, clear the flag.
+	if (err != KErrNone)
+		{
+		iCallbackFromAdaptor = KCallbackNone;
+		}
+	DP0_RET(err,"%d");
+	}
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::BufferErrorEvent
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::BufferErrorEvent()
+	{
+	ProcessingUnitError(NULL,KErrNoMemory);
+	}
+
+
+// -----------------------------------------------------------------------------
+// CDevPlayControl::FinishWithError
+// -----------------------------------------------------------------------------
+//
+void CDevPlayControl::FinishWithError(TInt aError)
+    {
+    iAdaptationObserver->PlayError(aError);
+    }
+
+// ---------------------------------------------------------------------------
+// CDevPlayControl::ProcessingError
+// ---------------------------------------------------------------------------
+TInt CDevPlayControl::ProcessingError(TBool& aAyncOperation)
+    {
+    TInt err = ProcessingFinishedReceived(aAyncOperation);
+    return err;
+    }
+    
+// End of file
+