os/mm/devsound/a3fdevsound/src/devsoundadaptor/cdevplaycontrol.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 
    17 
    18 #include "cdevplaycontrol.h"
    19 
    20 #include <a3f/maudiocontext.h>
    21 #include <a3f/mbuffersource.h>
    22 #include <a3f/maudiocodec.h>
    23 #include <a3f/maudiogaincontrol.h>
    24 #include <a3f/audioprocessingunittypeuids.h>
    25 
    26 
    27 // ---------------------------------------------------------------------------
    28 // Default constructor
    29 // ---------------------------------------------------------------------------
    30 //
    31 CDevPlayControl::CDevPlayControl()
    32 	{
    33 	TRACE_CREATE();
    34 	DP_CONTEXT(CDevPlayControl::CDevPlayControl *CD1*, CtxDevSound, DPLOCAL);
    35 	DP_IN();
    36 	DP_OUT();
    37 	}
    38 
    39 // -----------------------------------------------------------------------------
    40 // Symbian 2nd phase constructor
    41 // -----------------------------------------------------------------------------
    42 //
    43 void CDevPlayControl::ConstructL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aAdaptationObserver)
    44 	{
    45 	DP_CONTEXT(CDevPlayControl::ConstructL *CD1*, CtxDevSound, DPLOCAL);
    46 	DP_IN();
    47 	CDevAudioControl::ConstructL(aDevAudio, aAdaptationObserver);
    48 	DP_OUT();
    49 	}
    50 
    51 // -----------------------------------------------------------------------------
    52 // Symbian constructor
    53 // -----------------------------------------------------------------------------
    54 //
    55 CDevPlayControl* CDevPlayControl::NewL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aDevSoundObserver)
    56 	{
    57 	DP_STATIC_CONTEXT(CDevPlayControl::NewL *CD0*, CtxDevSound, DPLOCAL);
    58 	DP_IN();
    59 	CDevPlayControl* self = new (ELeave) CDevPlayControl();
    60 	CleanupStack::PushL(self);
    61 	self->ConstructL(aDevAudio, aDevSoundObserver);
    62 	CleanupStack::Pop(self);
    63 	DP0_RET(self, "0x%x");
    64 	}
    65 
    66 // ---------------------------------------------------------------------------
    67 // Destructor
    68 // ---------------------------------------------------------------------------
    69 //
    70 CDevPlayControl::~CDevPlayControl()
    71 	{
    72 	DP_CONTEXT(CDevPlayControl::~CDevPlayControl *CD1*, CtxDevSound, DPLOCAL);
    73 	DP_IN();
    74 	DP_OUT();
    75 	}
    76 
    77 // -----------------------------------------------------------------------------
    78 // CDevPlayControl::Initialize
    79 // -----------------------------------------------------------------------------
    80 //
    81 TInt CDevPlayControl::Initialize(TUid aFormat)
    82 	{
    83 	DP_CONTEXT(CDevPlayControl::Initialize *CD1*, CtxDevSound, DPLOCAL);
    84 	DP_IN();
    85 	ASSERT(iDevAudio->iAudioSource && iDevAudio->iAudioCodec && iGainControl);
    86 	TInt err(KErrNone);
    87 
    88 	err = iDevAudio->iAudioStream->AddSource(iDevAudio->iAudioSource);
    89 	if (err == KErrNone)
    90 		{
    91 		err = iDevAudio->iAudioStream->AddSink(iDevAudio->iAudioSink);
    92 		if (err == KErrNone)
    93 			{
    94 			err = iDevAudio->iAudioStream->AddAudioCodec(iDevAudio->iAudioCodec);
    95 			}
    96 		}
    97 	
    98 	if(err == KErrNone && iDevAudio->iActiveState == EDevSoundAdaptorCreated_Uninitialised)
    99 		{
   100 		// Register for notifications
   101 		// Note KErrAlreadyExist is not acceptable as an error, since it shouldn't occurr 
   102 		// It's mandatory unregister any observer when no more events are required
   103 		// Otherwise the notifications will be sent to all previously registered observer
   104 		// when reinitialising for different mode
   105 		err = iDevAudio->iAudioStream->RegisterAudioStreamObserver(*this);
   106 		if (err == KErrNone)
   107 			{
   108 			err = iGainControl->RegisterAudioGainControlObserver(*this);
   109 			if (err == KErrNone)
   110 				{
   111 				err = CacheAudioCodecIf();
   112 				if (err == KErrNone)
   113 					{
   114 					__ASSERT_ALWAYS (iAudioCodecIf,CDevAudioControl::Panic(EAudioCodecIsNull));
   115 					err = iAudioCodecIf->RegisterAudioCodecObserver(*this);
   116 					if(err == KErrNone)
   117 						{
   118 						err = iAudioCodecIf->SetFormat(aFormat);
   119 						if (err == KErrNone)
   120 							{
   121 							// Needed to get ProcessingUnitError notification 
   122 							err = iDevAudio->iAudioCodec->RegisterProcessingUnitObserver(*this);
   123 							}
   124 						}
   125 					}
   126 				}
   127 			}
   128 
   129 		if (err != KErrNone)
   130 			{
   131 			DP0(DLINFO,"Error while registering observers");
   132 			iDevAudio->iAudioStream->UnregisterAudioStreamObserver(*this);
   133 			iGainControl->UnregisterAudioGainControlObserver(*this);
   134 			if(iAudioCodecIf)
   135 				{
   136 				iAudioCodecIf->UnregisterAudioCodecObserver(*this);
   137 				iAudioCodecIf = NULL; // Not owned here: convenience pointer, so no need to delete
   138 				}
   139 			}
   140 
   141 		if (err == KErrNone)
   142 			{
   143 			err = iDevAudio->iAudioStream->Initialize();
   144 			if (err == KErrNone)
   145 				{
   146 				err = iDevAudio->CommitAudioContext();
   147 				if (err == KErrNone)
   148 					{
   149 					iDevAudio->iActiveState = EDevSoundAdaptorInitialising;
   150 					}
   151 				}
   152 			}
   153 		}
   154 	DP0_RET(err,"%d");
   155 	}
   156 
   157 // -----------------------------------------------------------------------------
   158 // CDevPlayControl::ProcessInit
   159 // -----------------------------------------------------------------------------
   160 //
   161 TInt CDevPlayControl::ProcessInit()
   162 	{
   163 	DP_CONTEXT(CDevPlayControl::ProcessInit *CD1*, CtxDevSound, DPLOCAL);
   164 	DP_IN();
   165 	PRF(PRF_ID, PRF_START, PRF_TIME, AA_DS_PlayInit, "");
   166 	PRF(PRF_ID, PRF_START, PRF_LOAD, AA_DS_Play, "");
   167 	TInt err(KErrNone);
   168 	
   169 	switch (iDevAudio->iActiveState)
   170 		{
   171 		case EDevSoundAdaptorInitialised_Initialised:
   172 			{
   173 			TAny* interface(NULL);
   174 			// get correct BufferSource interface of DevAudio::iAudioSource
   175 			interface = iDevAudio->iAudioSource->Interface(KUidMmfBufferSource);
   176 			
   177 			if (interface == NULL)
   178 				{
   179 				DP0_RET(KErrNotSupported, "Incorrect source type! %d");
   180 				}
   181 			else
   182 				{
   183 				iBufferSource = static_cast<MMMFBufferSource*>(interface);
   184 				iBufferSource->SetDataSupplier(*this);
   185 				if (iDevAudio->IsPrioritySet())
   186 					{
   187 					TAudioTypeSettings priority;
   188 					iDevAudio->GetPrioritySettings(priority);
   189 					err = iDevAudio->iAudioStream->SetAudioType(priority);
   190 					}				
   191 				}
   192 			if ( err == KErrNone)
   193 				{
   194 				err = iDevAudio->iAudioStream->Load();
   195 				}
   196 			if ( err == KErrNone)
   197 				{
   198 				err = iDevAudio->CommitAudioContext();
   199 				}
   200 			if(err == KErrNone)
   201 				{
   202 				iDevAudio->iActiveState = EDevSoundAdaptorLoading;
   203 				}
   204 			}
   205 			break;
   206 
   207 		case EDevSoundAdaptorGoingActive:
   208 			{
   209 			//If following condition is false, then we are here because of a
   210 			//pre-emption clash in last Commit cycle started from
   211 			//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
   212 			if(iDevAudio->iPreviousState != EDevSoundAdaptorActivating)
   213 				{
   214 				break;
   215 				}
   216 			//Fall through as required
   217 			}
   218 		case EDevSoundAdaptorPaused_Primed:
   219 		case EDevSoundAdaptorInitialised_Idle:
   220 			{
   221 			//If following condition is true, then we are here because of a
   222 			//pre-emption clash in last Commit cycle started from
   223 			//CDevCommonControl::ContextEventUpdateWithStateEventAndError.
   224 			if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
   225 				{
   226 				err = Unload();
   227 				break;
   228 				}
   229 
   230 			err = iDevAudio->RequestGainAndBalance(this);
   231 			if (err==KErrNone)
   232 				{
   233 				err = iDevAudio->iAudioStream->Activate();
   234 				}
   235 			if (err == KErrNone)
   236 				{
   237 				err = iDevAudio->CommitAudioContext();
   238 				}
   239 			if (err == KErrNone)
   240 				{
   241 				iDevAudio->iActiveState = EDevSoundAdaptorActivating;
   242 				}
   243 			break;
   244 			}
   245 		case EDevSoundAdaptorActive_Active:
   246 			// Deliberate fall through - set err=KErrNotReady for PlayInit when already active
   247 		default:
   248 			err = KErrNotReady;
   249 			break;
   250 		}
   251 
   252 	if(err == KErrNone)
   253 		{
   254 		iDevAudio->iStop = EFalse;
   255 		}
   256 	
   257 	DP0_RET(err,"%d");
   258 	}
   259 
   260 // -----------------------------------------------------------------------------
   261 // CDevPlayControl::ProcessData
   262 // -----------------------------------------------------------------------------
   263 //
   264 void CDevPlayControl::ProcessData()
   265 	{
   266 	DP_CONTEXT(CDevPlayControl::ProcessData *CD1*, CtxDevSound, DPLOCAL);
   267 	DP_IN();
   268 	TInt err(KErrNone);
   269 	
   270 	if(!iDevAudio->iStop)
   271 		{
   272 		err = iBufferSource->BufferFilled(iBuffer);
   273 		if ( err != KErrNone)
   274 			{
   275 			iErrorCondition = err;
   276 			Stop();
   277 			}
   278 		}
   279 
   280 	DP_OUT();
   281 	}
   282 
   283 // -----------------------------------------------------------------------------
   284 // From class MAudioDataSupplier
   285 // CDevPlayControl::BufferToBeFilled
   286 // -----------------------------------------------------------------------------
   287 //
   288 void CDevPlayControl::BufferToBeFilled(MMMFBufferSource* aSource, CMMFBuffer* aBuffer)
   289 	{
   290 	DP_CONTEXT(CDevPlayControl::BufferToBeFilled *CD1*, CtxDevSound, DPLOCAL);
   291 	DP_IN();
   292 	PRF(PRF_ID, PRF_STOP, PRF_TIME, AA_DS_PlayInit, "");
   293 	__ASSERT_ALWAYS(iBufferSource==aSource, CDevAudioControl::Panic(EBufferMismatch));
   294 	iAdaptationObserver->BufferToBeFilled(aBuffer);
   295 	iBuffer = aBuffer;
   296 	DP_OUT();
   297 	}
   298 
   299 // -----------------------------------------------------------------------------
   300 // From class MAudioDataSupplier
   301 // CDevPlayControl::DiscardBuffers
   302 // -----------------------------------------------------------------------------
   303 //
   304 void CDevPlayControl::DiscardBuffers(MMMFBufferSource* /*aSource*/)
   305 	{
   306 	DP_CONTEXT(CDevPlayControl::DiscardBuffers *CD1*, CtxDevSound, DPLOCAL);
   307 	DP_IN();
   308 
   309 	DP_OUT();
   310 	}
   311 
   312 // -----------------------------------------------------------------------------
   313 // CDevPlayControl::ProcessingFinished
   314 // -----------------------------------------------------------------------------
   315 //
   316 void CDevPlayControl::ProcessingFinished(MAudioStream& /*aStream*/)
   317 	{
   318 	DP_CONTEXT(CDevPlayControl::ProcessingFinished *CD1*, CtxDevSound, DPLOCAL);
   319 	DP_IN();
   320 	PRF(PRF_ID, PRF_STOP, PRF_LOAD, AA_DS_Play, "");
   321 	
   322 	if(iCallbackFromAdaptor == KCallbackNone)
   323 		{
   324 		iCallbackFromAdaptor = KCallbackProcessingFinished;
   325 		iAdaptationObserver->CallbackFromAdaptorReceived(iCallbackFromAdaptor, KErrNone);
   326 		}
   327 	else
   328 		{
   329 		// Multiple callbacks from adaptor
   330 		DP0(DLERR, "Multiple callbacks from adaptor");
   331 		}
   332 	DP_OUT();
   333 	}
   334 
   335 
   336 // -----------------------------------------------------------------------------
   337 // CDevPlayControl::ProcessingFinishedReceived
   338 // -----------------------------------------------------------------------------
   339 //
   340 TInt CDevPlayControl::ProcessingFinishedReceived(TBool& aAyncOperation)
   341 	{
   342 	DP_CONTEXT(CDevPlayControl::ProcessingFinishedReceived *CD1*, CtxDevSound, DPLOCAL);
   343 	DP_IN();
   344 	aAyncOperation = EFalse;
   345 	TInt err = iDevAudio->iAudioStream->Stop();
   346 	if ( err == KErrNone)
   347 		{
   348 		err = iDevAudio->CommitAudioContext();
   349 		if(err == KErrNone)
   350 			{
   351 			iDevAudio->iActiveState = EDevSoundAdaptorStopping;
   352 			aAyncOperation = ETrue;
   353 			}
   354 		}
   355 	// Something was wrong, clear the flag.
   356 	if (err != KErrNone)
   357 		{
   358 		iCallbackFromAdaptor = KCallbackNone;
   359 		}
   360 	DP0_RET(err,"%d");
   361 	}
   362 
   363 // -----------------------------------------------------------------------------
   364 // CDevPlayControl::BufferErrorEvent
   365 // -----------------------------------------------------------------------------
   366 //
   367 void CDevPlayControl::BufferErrorEvent()
   368 	{
   369 	ProcessingUnitError(NULL,KErrNoMemory);
   370 	}
   371 
   372 
   373 // -----------------------------------------------------------------------------
   374 // CDevPlayControl::FinishWithError
   375 // -----------------------------------------------------------------------------
   376 //
   377 void CDevPlayControl::FinishWithError(TInt aError)
   378     {
   379     iAdaptationObserver->PlayError(aError);
   380     }
   381 
   382 // ---------------------------------------------------------------------------
   383 // CDevPlayControl::ProcessingError
   384 // ---------------------------------------------------------------------------
   385 TInt CDevPlayControl::ProcessingError(TBool& aAyncOperation)
   386     {
   387     TInt err = ProcessingFinishedReceived(aAyncOperation);
   388     return err;
   389     }
   390     
   391 // End of file
   392