mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioPlayController.cpp
changeset 0 71ca22bcf22a
child 7 709f89d8c047
child 12 5a06f39ad45b
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This file contains the base class from which specific audio
       
    15 *                play controllers are derived. This class encapsulates common
       
    16 *                behavior for all audio play controllers.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "AdvancedAudioPlayController.h"
       
    23 #include "AdvancedAudioResource.h"
       
    24 #include "DebugMacros.h"
       
    25 #include <AudioOutput.h>
       
    26 #include <MetaDataFieldContainer.h>
       
    27 #include <MetaDataUtility.h>
       
    28 #include <mmfformatimplementationuids.hrh>
       
    29 #include <mmfmeta.h>
       
    30 #include <MultimediaDataSourceEvents.h>
       
    31 #include <MultimediaDataSourceFactory.h>
       
    32 #include <oma2dcf.h>
       
    33 
       
    34 // KMdaRepeatForever constant is defined in this file
       
    35 #include <mda/common/resource.h>
       
    36 // CONSTANTS
       
    37 const TInt KOneThousandMilliSecond = 1000;      // 1 sec
       
    38 
       
    39 // ============================= LOCAL FUNCTIONS ===============================
       
    40 
       
    41 // ============================ MEMBER FUNCTIONS ===============================
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CAdvancedAudioPlayController::CAdvancedAudioPlayController
       
    45 // C++ default constructor can NOT contain any code, that might leave.
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 EXPORT_C CAdvancedAudioPlayController::CAdvancedAudioPlayController()
       
    49 	:	iState(EStopped),
       
    50 		iAudioOutput(NULL),
       
    51 		iAudioResource(NULL),
       
    52 		iAudioUtility(NULL),
       
    53 		iDisableAutoIntent (EFalse),
       
    54     iDecoderExists(EFalse),
       
    55     iRepeatCount(-1),
       
    56     iCurrentRepeatCount(0),
       
    57     iLoopPlayEnabled(EFalse),
       
    58     iRepeatForever(EFalse),
       
    59     iTrailingSilenceMs(0),
       
    60     iSavedTimePositionInMicroSecs(0) //,
       
    61 	{
       
    62     iEventsEnabled = EFalse;
       
    63 
       
    64     RThread().SetPriority(EPriorityRealTime);
       
    65     }
       
    66 
       
    67 EXPORT_C void CAdvancedAudioPlayController::ConstructL()
       
    68 	{
       
    69 	DP1(_L("CAdvancedAudioPlayController::ConstructL this[%x]"), this);
       
    70 	CAdvancedAudioController::ConstructL();
       
    71 
       
    72     // Construct custom command parsers
       
    73     CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser =
       
    74     	CMMFAudioPlayDeviceCustomCommandParser::NewL(*this);
       
    75     CleanupStack::PushL(audPlayDevParser);
       
    76     AddCustomCommandParserL(*audPlayDevParser);
       
    77     CleanupStack::Pop(audPlayDevParser);
       
    78 
       
    79     CMMFAudioPlayControllerCustomCommandParser* audPlayConParser =
       
    80     	CMMFAudioPlayControllerCustomCommandParser::NewL(*this);
       
    81     CleanupStack::PushL(audPlayConParser);
       
    82     AddCustomCommandParserL(*audPlayConParser);
       
    83     CleanupStack::Pop(audPlayConParser);
       
    84 
       
    85 	CMMFDRMCustomCommandParser* drmParser = CMMFDRMCustomCommandParser::NewL(*this);
       
    86 	CleanupStack::PushL(drmParser);
       
    87 	AddCustomCommandParserL(*drmParser);
       
    88 	CleanupStack::Pop(drmParser);
       
    89 
       
    90     CStreamControlCustomCommandParser* scCCParser = CStreamControlCustomCommandParser::NewL(*this);
       
    91     CleanupStack::PushL(scCCParser);
       
    92     AddCustomCommandParserL(*scCCParser);
       
    93     CleanupStack::Pop(scCCParser);
       
    94 
       
    95     // new custom command parser to implement the MapcSetRepeats custom command from the client
       
    96     CMMFAudioPlayControllerSetRepeatsCustomCommandParser* audPlayConSetRepeatsParser =
       
    97             CMMFAudioPlayControllerSetRepeatsCustomCommandParser::NewL(*this);
       
    98     CleanupStack::PushL(audPlayConSetRepeatsParser);
       
    99     AddCustomCommandParserL(*audPlayConSetRepeatsParser);
       
   100     CleanupStack::Pop(audPlayConSetRepeatsParser);
       
   101 	}
       
   102 
       
   103 // Destructor
       
   104 EXPORT_C CAdvancedAudioPlayController::~CAdvancedAudioPlayController()
       
   105     {
       
   106     DP1(_L("CAdvancedAudioPlayController::~CAdvancedAudioPlayController start this[%x]"), this);
       
   107     DP4(_L("CAdvancedAudioPlayController::~CAdvancedAudioPlayController iState[%d] iWait[%d] iBlockSetPos[%d] iSharedBuffers.Count[%d]"),
       
   108             iState, iWait, iBlockSetPos, iSharedBuffers.Count());
       
   109 	RThread().SetPriority(EPriorityNormal);
       
   110 
       
   111     if (iMetaDataEntries.Count())
       
   112     	{
       
   113         iMetaDataEntries.ResetAndDestroy();
       
   114 		iMetaDataEntries.Close();
       
   115 		}
       
   116 		
       
   117     if (iTrailingSilenceTimer)
       
   118         {
       
   119         delete iTrailingSilenceTimer;
       
   120         iTrailingSilenceTimer = NULL;
       
   121         }
       
   122 
       
   123 	delete iDataSourceAdapter;
       
   124 	delete iWait;
       
   125 	delete iBlockSetPos;
       
   126 	iSharedBuffers.ResetAndDestroy();
       
   127 	iSharedBuffers.Close();
       
   128     DP0(_L("CAdvancedAudioPlayController::~CAdvancedAudioPlayController end"));
       
   129     }
       
   130 
       
   131     
       
   132 // -----------------------------------------------------------------------------
       
   133 // CAdvancedAudioPlayController::DoReadHeaderL
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 EXPORT_C void CAdvancedAudioPlayController::DoReadHeaderL(CMMFDataBuffer* /*aBuffer*/)
       
   137     {
       
   138     // do nothing
       
   139     }
       
   140     
       
   141 // -----------------------------------------------------------------------------
       
   142 // CAdvancedAudioPlayController::DoSetPositionL
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 EXPORT_C void CAdvancedAudioPlayController::DoSetPositionL(const TTimeIntervalMicroSeconds& aTimePos)
       
   146     {
       
   147     DP0(_L("CAdvancedAudioPlayController::DoSetPositionL start -----------"));
       
   148     TInt err = KErrNone;
       
   149     TInt foundPosition;
       
   150     TInt foundTimeMs;
       
   151     TBool seekFwd = EFalse;
       
   152 	TUint timeMs = aTimePos.Int64()/1000;
       
   153     DP2(_L("CAdvancedAudioPlayController::DoSetPositionL timeMs[%u] pre[%d]"), timeMs, (iPreSeekTime.Int64()/1000));
       
   154     // Fix for the error ou1cimx1#151598 - ESLM-7T5GJH
       
   155     // unregisters any old position entries from the FrameTable before setting any new play seek positions
       
   156     iAudioUtility->SeekToTimeMs(KMaxTUint);
       
   157 
       
   158 	if (aTimePos < 0)
       
   159 		{
       
   160 		timeMs = 0;
       
   161 		}
       
   162 		
       
   163     // get current position in time
       
   164     // if we need to play to seek forward (not in table), the time will be advanced immediately
       
   165     // if we pause before we get there, pause will set pos to that time - which is what we want.
       
   166     // but we need to remember that we are not there yet so we can still seek forward. So we use pre-seek time.
       
   167     if (!iPlaySeeking)
       
   168         {
       
   169         iPreSeekTime = PositionL();
       
   170 	    DP1(_L("CAdvancedAudioPlayController::DoSetPositionL save pre-seek time[%d]"), iPreSeekTime.Int64()/1000);
       
   171         }
       
   172     if (aTimePos > iPreSeekTime)
       
   173     	{
       
   174     	seekFwd = ETrue;
       
   175     	}
       
   176     DP1(_L("CAdvancedAudioPlayController::DoSetPositionL seekFwd[%d]"), seekFwd);
       
   177 
       
   178    	TUint const seekTime = timeMs;
       
   179     TUint position = 0;
       
   180     TBool posFoundInTable = EFalse;
       
   181     
       
   182     // look in current buffers first
       
   183     DP0(_L("CAdvancedAudioPlayController::DoSetPositionL not time seekable"));
       
   184     err = SetPositionInSharedBuffers(timeMs, foundPosition, foundTimeMs);
       
   185     if (!iSourceIsTimeSeekable && !iSourceIsPosSeekable)
       
   186         { 
       
   187     	if (err == KErrNone)
       
   188 	        { // found exact position
       
   189 		    DP0(_L("CAdvancedAudioPlayController::DoSetPositionL found exact position"));
       
   190     	    iCurrentPosition = foundPosition; // absolute position into file or content
       
   191         	iTimePositionInMicroSecs = foundTimeMs;
       
   192         	iTimePositionInMicroSecs *=1000;
       
   193             DP1(_L("CAdvancedAudioPlayController::DoSetPositionL iTimePositionInMicroSecs[%d]"),foundTimeMs);
       
   194 			iAudioUtility->SetSourceReference(iTimePositionInMicroSecs/1000, iCurrentPosition-iHeaderOffset-iSyncOffset);
       
   195 		    RefillPreceedingBuffersL();
       
   196     		DP0(_L("CAdvancedAudioPlayController::DoSetPositionL end -----------"));
       
   197     	    return;
       
   198         	}
       
   199 	    // err means it just found something close
       
   200         ASSERT(err != KErrGeneral);
       
   201         if (err == KErrGeneral)
       
   202             { // KErrGeneral means it did not find anything and we have to stop.
       
   203     		DP0(_L("CAdvancedAudioPlayController::DoSetPositionL abort -------"));
       
   204     		TMMFEvent event(KMMFEventCategoryPlaybackComplete,KErrGeneral);
       
   205     		SendEvent(event);
       
   206             return;
       
   207             }
       
   208         // source is not seekable so use buffered data
       
   209 	    // use closest time and position found above
       
   210 		DP0(_L("CAdvancedAudioPlayController::DoSetPositionL using closest position"));
       
   211     	iCurrentPosition = foundPosition;
       
   212         iTimePositionInMicroSecs = foundTimeMs;
       
   213         iTimePositionInMicroSecs *=1000;
       
   214         DP1(_L("CAdvancedAudioPlayController::DoSetPositionL iTimePositionInMicroSecs[%d]"),foundTimeMs);
       
   215 		iAudioUtility->SetSourceReference(iTimePositionInMicroSecs/1000, iCurrentPosition-iHeaderOffset-iSyncOffset);
       
   216 		RefillPreceedingBuffersL();
       
   217         }
       
   218     if (iSourceIsTimeSeekable)
       
   219 	  	{ // time seekable source won't have accurate table positions
       
   220 	    DP0(_L("CAdvancedAudioPlayController::DoSetPositionL is time seekable"));
       
   221         iPreSeekTime = 0;
       
   222 		iDataSourceAdapter->SourceStopL(); // clear the buffers in the source before seeking and priming it
       
   223 		iDataSourceAdapter->SourcePrimeL();
       
   224 	  	err = iDataSourceAdapter->SeekToTime(seekTime, timeMs);
       
   225 	    iAudioUtility->ResetTable();
       
   226 		iDataSourceAdapter->SourcePlayL();
       
   227 		iTimePositionInMicroSecs = timeMs;
       
   228 		iTimePositionInMicroSecs *=1000;
       
   229         DP1(_L("CAdvancedAudioPlayController::DoSetPositionL iTimePositionInMicroSecs[%d]"),timeMs);
       
   230 		iSourceReadPosition = 0; // we don't know the position - source doesn't give us that
       
   231 	    // iCurrentPosition = iSourceReadPosition;
       
   232 		iCurrentPosition = KMaxTUint;
       
   233 		iAudioUtility->SetSourceReference(iTimePositionInMicroSecs/1000, 0);
       
   234         TRAP(err, RefillSharedBuffersL());
       
   235     	}
       
   236     else if (iSourceIsPosSeekable)
       
   237     	{
       
   238 	    DP0(_L("CAdvancedAudioPlayController::DoSetPositionL is position seekable"));
       
   239 	    TInt err = iAudioUtility->FindFramePosFromTime(timeMs, position);
       
   240 	    if (err == KErrNone)
       
   241     		{
       
   242    			DP0(_L("CAdvancedAudioPlayController::DoSetPositionL pos found in table"));
       
   243     		posFoundInTable = ETrue;
       
   244     		}
       
   245 	    TBool tryForAccuracy = EFalse;
       
   246 		if (posFoundInTable)
       
   247 			{ // seek in source is taken care of below
       
   248 			// The position was found in the table, and assuming it was found in the low res table
       
   249 			// lets try to seek fwd to the exact position.
       
   250 			// The reason for this is that the record utility does a stop play instead of a pause play
       
   251 			// The inaccuracy in the resume position is then visible, using the low res table.
       
   252 			tryForAccuracy = ETrue;
       
   253 			}
       
   254 		else
       
   255 			{ // then we must be going forward or just starting
       
   256    			DP0(_L("CAdvancedAudioPlayController::DoSetPositionL pos not found in table"));
       
   257    			err = iAudioUtility->LastFramePos(position);
       
   258    			if (err) // use KErrDoesNotExist or something
       
   259    				{ // do this a little better, maybe return something different from LastFramePos
       
   260    				position = 0;
       
   261    				timeMs = 0;
       
   262    				}
       
   263    			else
       
   264 	   			{
       
   265 			    err = iAudioUtility->FindFrameTimeFromPos(timeMs, position);
       
   266    				}	
       
   267 			}
       
   268 		// seek in source		
       
   269 		DP0(_L("CAdvancedAudioPlayController::DoSetPositionL seek in the source"));
       
   270 	    iSourceReadPosition = position+iHeaderOffset+iSyncOffset;
       
   271 		iDataSourceAdapter->SourceStopL(); // clear the buffers in the source before seeking and priming it
       
   272 		iDataSourceAdapter->SourcePrimeL();
       
   273 	    iDataSourceAdapter->SeekToPosition(iSourceReadPosition);
       
   274 	    iAudioUtility->ResetTable();
       
   275 		iDataSourceAdapter->SourcePlayL();
       
   276 	    iCurrentPosition = iSourceReadPosition;
       
   277 	    iTimePositionInMicroSecs = timeMs;
       
   278 	    iTimePositionInMicroSecs *=1000; // bh 21Mar08 // need this time to correlate to the position found
       
   279         DP1(_L("CAdvancedAudioPlayController::DoSetPositionL iTimePositionInMicroSecs[%d]"),timeMs);
       
   280 		iAudioUtility->SetSourceReference(iTimePositionInMicroSecs/1000, iCurrentPosition-iHeaderOffset-iSyncOffset);
       
   281         TRAP(err, RefillSharedBuffersL());
       
   282 		DP1(_L("CAdvancedAudioPlayController::DoSetPositionL RefillSharedBuffersL[%d]"),err);
       
   283         if (seekFwd && (!posFoundInTable || tryForAccuracy))
       
   284            	{
       
   285 			// seeking forward past entries available in table
       
   286 			// will scan buffers for frame lengths without rendering 
       
   287 			// which will add table entries and notify when pos is reached
       
   288    			DP0(_L("CAdvancedAudioPlayController::DoSetPositionL do non-render seek fwd"));
       
   289            	SeekToTimeMsL(seekTime); // this will set iTimePositionInMicroSecs to the seek fwd time
       
   290            	}
       
   291        	else
       
   292        	    {
       
   293             iPreSeekTime = 0;
       
   294        	    }
       
   295     	}
       
   296     else
       
   297         { // continue from closest position and render once the time is reached
       
   298 		DP0(_L("CAdvancedAudioPlayController::DoSetPositionL src not seekable continue"));
       
   299 		if (seekFwd)
       
   300 			{
       
   301 			DP0(_L("CAdvancedAudioPlayController::DoSetPositionL src not seekable do non-render seek fwd"));
       
   302 	       	SeekToTimeMsL(seekTime);
       
   303 			}
       
   304         }
       
   305     DP0(_L("CAdvancedAudioPlayController::DoSetPositionL end -----------"));
       
   306     }
       
   307     
       
   308 void CAdvancedAudioPlayController::SeekToTimeMsL(TUint aTimeMs)
       
   309 	{ // used when seeking forward without rendering
       
   310 	DP1(_L("CAdvancedAudioPlayController::SeekToTimeMs[%d]"),aTimeMs);
       
   311 
       
   312 	iAudioUtility->SeekToTimeMs(aTimeMs);
       
   313 	iPlaySeeking = ETrue;
       
   314 	// ok to set the time forward because during this seek, devsound won't be getting
       
   315 	// any data - so it's samples played would stay 0 and not keep incrementing if position is called
       
   316     iTimePositionInMicroSecs = aTimeMs;
       
   317     iTimePositionInMicroSecs *=1000;
       
   318     DP1(_L("CAdvancedAudioPlayController::SeekToTimeMs iTimePositionInMicroSecs[%d]"),iTimePositionInMicroSecs);
       
   319     if (iState == EPaused)
       
   320         {
       
   321         PlayForPauseSeekL();
       
   322         }
       
   323     else if (iState == EInitialized)
       
   324     	{
       
   325 		PlayForInitPositionL();
       
   326     	}
       
   327 	}
       
   328     
       
   329 void CAdvancedAudioPlayController::GoToInitPositionL()
       
   330 	{
       
   331     DP1(_L("CAdvancedAudioPlayController::GoToInitPositionL[%d]"),iInitPosition.Int64());
       
   332 	if (iInitPosition >= 0)
       
   333 		{ // -1 is inactive, >=0 will seek
       
   334 		TTimeIntervalMicroSeconds position = iInitPosition;
       
   335 	    DP0(_L("CAdvancedAudioPlayController::GoToInitPositionL clearing iInitPosition and seeking"));
       
   336 		iInitPosition = -1;		
       
   337 		DoSetPositionL(position);
       
   338 		}
       
   339     // Register for the Playwindow end position, if PlayWindow is created
       
   340     if (iPlayWindowEndPosition > 0)
       
   341         {
       
   342         iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64()/1000);
       
   343         }
       
   344 	}
       
   345     
       
   346 // -----------------------------------------------------------------------------
       
   347 // CAdvancedAudioPlayController::RefillSharedBuffersL
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CAdvancedAudioPlayController::RefillSharedBuffersL()
       
   351     {
       
   352 	DP0(_L("CAdvancedAudioPlayController::RefillSharedBuffersL"));
       
   353     TInt i;
       
   354     ClearSharedBuffersL();
       
   355     for (i=0; i < iSharedBufferMaxNum; i++)
       
   356         {
       
   357         FillSharedBufferL(iSharedBuffers[i]);
       
   358         }
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CAdvancedAudioPlayController::ReinitSharedBuffersL
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 void CAdvancedAudioPlayController::ClearSharedBuffersL()
       
   366     {
       
   367 	DP0(_L("CAdvancedAudioPlayController::ClearSharedBuffersL"));
       
   368     for (TInt i=0; i < iSharedBufferMaxNum; i++)
       
   369         {
       
   370     	static_cast<CMMFDataBuffer*>(iSharedBuffers[i])->Data().SetLength(0);
       
   371     	iSharedBuffers[i]->SetLastBuffer(EFalse);
       
   372     	iSharedBuffers[i]->SetStatus(EAvailable);
       
   373         }
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CAdvancedAudioPlayController::InitSharedBuffersL
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 EXPORT_C void CAdvancedAudioPlayController::InitSharedBuffersL()
       
   381     {
       
   382 	DP0(_L("CAdvancedAudioPlayController::InitSharedBuffersL"));
       
   383     TInt i;
       
   384 	ResetSharedBuffersL(iSharedBufferMaxNum, iSharedBufferMaxSize);
       
   385     for (i=0; i < iSharedBufferMaxNum; i++)
       
   386         {
       
   387         FillSharedBufferL(iSharedBuffers[i]);
       
   388         }
       
   389     }
       
   390 
       
   391 EXPORT_C void CAdvancedAudioPlayController::RefillPreceedingBuffersL()
       
   392 	{
       
   393 	DP0(_L("CAdvancedAudioPlayController::RefillPreceedingBuffersL"));
       
   394 	TInt curIndex = iSharedBufferIndex;
       
   395 	TInt curPos = iSharedBuffers[curIndex]->FrameNumber();
       
   396 	TInt maxNum = iSharedBufferMaxNum;
       
   397 	// buffers are filled in increasing order
       
   398 	TInt index = iSharedBufferIndex;
       
   399 	TInt pos;
       
   400 	TInt stat;
       
   401 	for (TInt i=0; i< maxNum-1; i++)
       
   402 		{
       
   403 		index++;
       
   404 		if (index >= maxNum)
       
   405 			{
       
   406 			index = 0;
       
   407 			}
       
   408         stat = iSharedBuffers[index]->Status();
       
   409 		pos = iSharedBuffers[index]->FrameNumber();
       
   410 		DP4(_L("CAdvancedAudioPlayController::RefillPreceedingBuffersL index[%d] stat[%d] pos[%d] bufpos[%d]"), 
       
   411 				index, stat, pos, iSharedBuffers[index]->Position());
       
   412 		if ((pos < curPos) && (stat == EFull))
       
   413 			{
       
   414 			DP1(_L("CAdvancedAudioPlayController::RefillPreceedingBuffersL index[%d]"),index);
       
   415 	        FillSharedBufferL(iSharedBuffers[index]);
       
   416 			}
       
   417 		}
       
   418 	}
       
   419 
       
   420 // -----------------------------------------------------------------------------
       
   421 // CAdvancedAudioPlayController::SourceSinkStopL
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 EXPORT_C void CAdvancedAudioPlayController::SourceSinkStopL()
       
   425     {
       
   426 	iDataSourceAdapter->SourceStopL();
       
   427 
       
   428     if (iDataSink->DataSinkType() == KUidMmfFileSink)
       
   429         {
       
   430         iDataSink->SinkStopL();
       
   431         }
       
   432     }
       
   433     
       
   434 // -----------------------------------------------------------------------------
       
   435 // CAdvancedAudioPlayController::FillSharedBufferL
       
   436 // Read the next block of data from source into the given buffer.
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 EXPORT_C void CAdvancedAudioPlayController::FillSharedBufferL(
       
   440     CMMFBuffer* aBuffer)
       
   441     {
       
   442     DP2(_L("CAdvancedAudioPlayController::FillSharedBufferL ptr[%x], iState[%d]"),
       
   443             static_cast<CMMFDataBuffer*>(aBuffer)->Data().Ptr(), iState);
       
   444 
       
   445     aBuffer->SetLastBuffer(EFalse);
       
   446     aBuffer->SetStatus(EBeingFilled);
       
   447 	aBuffer->SetPosition(0);
       
   448 	static_cast<CMMFDataBuffer*>(aBuffer)->Data().SetLength(0);
       
   449 			
       
   450 	TMediaId mediaId(KUidMediaTypeAudio);
       
   451 	iDataSourceAdapter->FillBufferL(aBuffer, this, mediaId);
       
   452     }
       
   453     
       
   454 // -----------------------------------------------------------------------------
       
   455 // CAdvancedAudioPlayController::FindBufferFromPos
       
   456 // -----------------------------------------------------------------------------
       
   457 // aPos is relative to source position in that it includes any header offsets
       
   458 // Will return KErrNotFound if the position is not found in the buffers.
       
   459 // Will look only in full buffers.
       
   460 EXPORT_C TInt CAdvancedAudioPlayController::FindBufferFromPos(TUint aPos)
       
   461 	{
       
   462     DP1(_L("CAdvancedAudioPlayController::FindBufferFromPos, aPos[%d]"), aPos);
       
   463 
       
   464     TInt retVal = KErrNotFound;
       
   465     
       
   466     for (TInt i = 0; i < iSharedBufferMaxNum; i++)
       
   467         {
       
   468         DP5(_L("CAdvancedAudioPlayController::FindBufferFromPos iSharedBuffers[%d], ptr=%x, FrameNumber[%d], Status[%d], LastBuffer[%d]"), i, iSharedBuffers[i]->Data().Ptr(), iSharedBuffers[i]->FrameNumber(), iSharedBuffers[i]->Status(), iSharedBuffers[i]->LastBuffer());
       
   469         TUint framenumber = iSharedBuffers[i]->FrameNumber();
       
   470         TUint buffersize = iSharedBuffers[i]->BufferSize();
       
   471         DP6(_L("CAdvancedAudioPlayController::FindBufferFromPos iSharedBuffers[%d], ptr=%x, FrameNumber[%d], Status[%d], LastBuffer[%d], BufferSize[%d]"), i, iSharedBuffers[i]->Data().Ptr(), framenumber, iSharedBuffers[i]->Status(), iSharedBuffers[i]->LastBuffer(), buffersize);
       
   472         if ((aPos >= framenumber) && (aPos < (framenumber+buffersize)) &&
       
   473 //        if ((aPos >= framenumber) && (aPos < (framenumber+iSharedBufferMaxSize)) &&
       
   474         	(iSharedBuffers[i]->Status() == EFull))
       
   475             {
       
   476             iSharedBuffers[i]->SetPosition(aPos-framenumber);
       
   477             DP1(_L("CAdvancedAudioPlayController::FindBufferFromPos setting position to [%d]"), iSharedBuffers[i]->Position());
       
   478 			retVal = i;
       
   479 			break;
       
   480             }
       
   481         }
       
   482     DP1(_L("CAdvancedAudioPlayController::FindBufferFromPos retVal[%d]"), retVal);
       
   483 	return retVal;
       
   484 	}	
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // CAdvancedAudioPlayController::SetPositionInSharedBuffers
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 /*
       
   491 This function will look in current buffers that aren't being filled and set the
       
   492 buffer and position in it to the corresponding current time.
       
   493 An error will be returned if the exact position was not located in a full buffer.
       
   494 A closest available will be calculated. 
       
   495 The buffers past the set will be sent to be filled.
       
   496 If a buffer is full, it can be used.
       
   497 If it is being filled, it can not be used here.
       
   498 If a buffer is other than full or being filled, it should be sent to be filled
       
   499 in the correct sequence after the buffer position is determined.
       
   500 */
       
   501 EXPORT_C TInt CAdvancedAudioPlayController::SetPositionInSharedBuffers(TUint aTimeMs, TInt& aFoundPosition, TInt& aFoundTimeMs)
       
   502     {
       
   503     TInt err = KErrNone;
       
   504     TUint position;
       
   505     TUint timeMs;
       
   506 
       
   507     DP1(_L("CAdvancedAudioPlayController::SetPositionInSharedBuffersL -- start this[%x]"), this);
       
   508     
       
   509     for (TInt i = 0; i < iSharedBufferMaxNum; i++)
       
   510         {
       
   511         DP6(_L("CAdvancedAudioPlayController::SetPositionInSharedBuffersL iSharedBuffers[%d] ptr[%x] FrameNumber[%d] Status[%d] LastBuffer[%d] bufpos[%d]"),
       
   512          	i, iSharedBuffers[i]->Data().Ptr(), iSharedBuffers[i]->FrameNumber(), iSharedBuffers[i]->Status(), iSharedBuffers[i]->LastBuffer(), iSharedBuffers[i]->Position());
       
   513         
       
   514         if (iSharedBuffers[i]->Status() != EBeingFilled)
       
   515             { // reset the positions on the buffers that the source does not have
       
   516             iSharedBuffers[i]->SetPosition(0);
       
   517             }
       
   518         
       
   519         if (iSharedBuffers[i]->Status() == EBeingEmptied)
       
   520         	{
       
   521 	        iSharedBuffers[i]->SetStatus(EFull);
       
   522         	}
       
   523         }
       
   524     timeMs = aTimeMs;
       
   525     // get the closest position from the table for the given time
       
   526     err = iAudioUtility->FindFramePosFromTime(timeMs, position); // err indicates if position found, or just what was available
       
   527 	// see if the buffer with this position exists
       
   528     iSharedBufferIndex = FindBufferFromPos(position + iHeaderOffset + iSyncOffset);
       
   529 	TUint framenumber = 0;
       
   530 		
       
   531 	if (iSharedBufferIndex >= 0)
       
   532 	    {
       
   533 	    }
       
   534 	else
       
   535 	    {
       
   536         DP0(_L("CAdvancedAudioPlayController::SetPositionInSharedBuffersL, buffer not found"));
       
   537         err = KErrNotFound;
       
   538         // find a frame in current buffers
       
   539         TInt minindex = 0;
       
   540         TInt tempframenum = -1;
       
   541 
       
   542         for (TInt j = 0; j < iSharedBufferMaxNum; j++)
       
   543             {
       
   544             if (iSharedBuffers[j]->Status() == EFull)
       
   545             	{
       
   546 	            framenumber = iSharedBuffers[j]->FrameNumber();
       
   547             	}
       
   548 
       
   549             if (((framenumber < tempframenum) || (tempframenum == -1)) && 
       
   550                 (iSharedBuffers[j]->Status() == EFull))
       
   551                 {
       
   552                 tempframenum = framenumber;
       
   553                 minindex = j;
       
   554                 }
       
   555             }
       
   556 		if (tempframenum == -1)
       
   557 			{
       
   558 			return KErrNotFound;
       
   559 			}
       
   560 	    iSharedBufferIndex = minindex;
       
   561 	    framenumber = iSharedBuffers[iSharedBufferIndex]->FrameNumber();
       
   562 	    // find a frame start
       
   563 	    if (framenumber < (iHeaderOffset+iSyncOffset))
       
   564 	        { // special case for buffer that still has header info
       
   565 	        position = 0;
       
   566 	        timeMs = 0;
       
   567 	        }
       
   568 	    else
       
   569 	    	{
       
   570 		    position = framenumber-iHeaderOffset-iSyncOffset;
       
   571 		    TInt err1 = iAudioUtility->FindFrameTimeFromPos(timeMs, position);
       
   572 //#ifdef _DEBUG
       
   573 		    if (err1 != KErrNone)
       
   574 		    	{ // we have to find a location in the table for the buffers we have 
       
   575 		    	// amr may scan whole file and buffers won't contain start data
       
   576 		    	//   but it would only happen for seekable source
       
   577 	    	    DP0(_L("CAdvancedAudioPlayController::SetPositionInSharedBuffersL, position in buffers not found -- aborting"));
       
   578                 return KErrGeneral;
       
   579 //	    	    ASSERT(err1 == KErrNone);
       
   580 	    		}
       
   581 //#endif	    	
       
   582 	    	}
       
   583         }
       
   584            
       
   585     aFoundPosition = position + iHeaderOffset + iSyncOffset;
       
   586     aFoundTimeMs = timeMs;
       
   587     framenumber = iSharedBuffers[iSharedBufferIndex]->FrameNumber();
       
   588     iSharedBuffers[iSharedBufferIndex]->SetPosition(aFoundPosition-framenumber);
       
   589     // after this send buffers to be filled that need to be filled to maintain correct sequence.
       
   590     DP2(_L("CAdvancedAudioPlayController::SetPositionInSharedBuffersL, iSharedBufferIndex[%d] pos[%d]-- end"), 
       
   591     		iSharedBufferIndex, aFoundPosition-framenumber);
       
   592     return err;    
       
   593     }
       
   594 
       
   595 
       
   596 // -----------------------------------------------------------------------------
       
   597 // CAdvancedAudioPlayController::UpdateDuration
       
   598 //
       
   599 // Possible parameters are:
       
   600 // -1 = just update duration
       
   601 //  0 = triggers duration changed immediately
       
   602 //  a number = will trigger duration changed event if duration has changed this amount given
       
   603 // -----------------------------------------------------------------------------
       
   604 //
       
   605 EXPORT_C TInt CAdvancedAudioPlayController::UpdateDuration(TInt aLimitInMilliSecond)
       
   606     { // updates iDuration
       
   607     DP2(_L("CAdvancedAudioPlayController::UpdateDuration, iEventsEnabled[%d], aLimitInMilliSecond[%d]"), iEventsEnabled, aLimitInMilliSecond);
       
   608     
       
   609     if (iDurationFrozen)
       
   610         {
       
   611         return KErrNone;
       
   612         }
       
   613         
       
   614     if (aLimitInMilliSecond < -1)
       
   615         {
       
   616         return KErrArgument;
       
   617         }
       
   618 	
       
   619 	if (!iAudioUtility)
       
   620 		{
       
   621 		return KErrNone;
       
   622 		}
       
   623 		
       
   624     TInt64 duration = iAudioUtility->Duration(); // calculates new duration
       
   625     if ((aLimitInMilliSecond == -1) || !iEventsEnabled)
       
   626     	{
       
   627         iDuration = duration;
       
   628     	}
       
   629     else if ((iDuration != duration) && (Abs(duration-iDuration) >= (aLimitInMilliSecond*1000)))
       
   630         {
       
   631         iDuration = duration;
       
   632         SendEventToClient(TMMFEvent(KStreamControlEventDurationChanged, KErrNone));
       
   633         }
       
   634     DP1(_L("CAdvancedAudioPlayController::UpdateDuration, iDuration[%d]"), iDuration);
       
   635     return KErrNone;
       
   636     }
       
   637 
       
   638 EXPORT_C TInt CAdvancedAudioPlayController::UpdateBitRate()
       
   639     {
       
   640     DP0(_L("CAdvancedAudioPlayController::UpdateBitRate"));
       
   641     if (iBitRateFrozen)
       
   642         {
       
   643 	    DP0(_L("CAdvancedAudioPlayController::UpdateBitRate frozen"));
       
   644         return KErrNone;        
       
   645         }
       
   646     if (iAudioUtility)
       
   647         {
       
   648         iBitRate = iAudioUtility->BitRate();
       
   649 	    DP1(_L("CAdvancedAudioPlayController::UpdateBitRate iBitRate[%d]"), iBitRate);
       
   650         }
       
   651     return KErrNone;        
       
   652     }
       
   653     
       
   654 // -----------------------------------------------------------------------------
       
   655 // CAdvancedAudioPlayController::HandleAutoPauseEvent
       
   656 // -----------------------------------------------------------------------------
       
   657 //
       
   658 EXPORT_C void CAdvancedAudioPlayController::HandleAutoPauseEvent()
       
   659     {
       
   660     DP0(_L("CAdvancedAudioPlayController::HandleAutoPauseEvent"));
       
   661     iState = EAutoPaused;
       
   662     SendEventToClient(TMMFEvent(KStreamControlEventStateChangedAutoPaused, KErrNone));
       
   663     }
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CAdvancedAudioPlayController::HandlePreemptionEvent
       
   667 // -----------------------------------------------------------------------------
       
   668 //
       
   669 EXPORT_C void CAdvancedAudioPlayController::HandlePreemptionEvent(TInt aError)
       
   670     {
       
   671     DP1(_L("CAdvancedAudioPlayController::HandlePreemptionEvent this[%x]"), this);
       
   672     TInt err;
       
   673 
       
   674 	// Stop the CActiveSchedulerWait for SetPosition if it is started during Playforseek
       
   675     if(iBlockSetPos)
       
   676         {
       
   677         if (iBlockSetPos->IsStarted())
       
   678             {
       
   679             iBlockSetPos->AsyncStop();
       
   680             }
       
   681         }
       
   682 
       
   683     iRequestState = EPaused;
       
   684     TRAP(err, DoPauseL(ETrue)); // this is a preemption pause
       
   685 	// In case of pre-emption we should only Pause ... but not Stop.
       
   686     SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, aError));
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CAdvancedAudioPlayController::HandleGeneralEvent
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 EXPORT_C void CAdvancedAudioPlayController::HandleGeneralEvent(const TMMFEvent& aEvent)
       
   694     {
       
   695     DP1(_L("CAdvancedAudioPlayController::HandleGeneralEvent this[%x]"), this);
       
   696     TRAP_IGNORE(DoStopL(aEvent.iErrorCode));
       
   697     }
       
   698     
       
   699 // -----------------------------------------------------------------------------
       
   700 // CAdvancedAudioPlayController::SetPlaybackWindowBoundariesL
       
   701 // -----------------------------------------------------------------------------
       
   702 //    
       
   703 EXPORT_C void CAdvancedAudioPlayController::SetPlaybackWindowBoundariesL(const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd)
       
   704     {
       
   705     DP2(_L("CAdvancedAudioPlayController::SetPlaybackWindowBoundariesL start[%d] end[%d]"), aStart.Int64(), aEnd.Int64());
       
   706 
       
   707     // if client calls SetPlayWindow with the same values then it can be ignored
       
   708     // as the controller may be in the middle of processing.
       
   709     if (iPlayWindowStartPosition == aStart && iPlayWindowEndPosition == aEnd)
       
   710         {
       
   711         return;
       
   712         }
       
   713 
       
   714 	if ( iPlayWindowStartPosition < TTimeIntervalMicroSeconds(0) )
       
   715 		{
       
   716 		iPlayWindowStartPosition = TTimeIntervalMicroSeconds(0);
       
   717 		}
       
   718 	else
       
   719 	    {
       
   720 	    iPlayWindowStartPosition = aStart;
       
   721 	    }
       
   722 
       
   723 	if ( iPlayWindowEndPosition < TTimeIntervalMicroSeconds(0) )
       
   724 		{
       
   725 		iPlayWindowEndPosition = TTimeIntervalMicroSeconds(0);
       
   726 		}
       
   727 	else
       
   728 	    {
       
   729 	    iPlayWindowEndPosition = aEnd;
       
   730 	    }
       
   731 
       
   732 	// We should not set the iInitPosition here because, if ClearPlayWindow is called when iState == EPlaying || EPaused
       
   733 	// then iInitPosition will be reset to zero, which should not be the case because the default iInitPosition should be -1.
       
   734 	// We just have to clear the play window end postion and continue to play from the current playback position
       
   735    	// iInitPosition = iPlayWindowStartPosition;
       
   736  	
       
   737 	DP2(_L("CAdvancedAudioPlayController::SetPlaybackWindowBoundariesL iPlayWindowStartPosition[%d] iPlayWindowEndPosition[%d]"), iPlayWindowStartPosition.Int64()/1000, iPlayWindowEndPosition.Int64()/1000);
       
   738 	// Registers / Unregisters the PlayWindowEndPosition depending on the aEnd value, whenever the play window is set / cleared
       
   739     // For SYMBIAN ClearPlayWindow(): If the ClearPlayWindow() is called during playing,
       
   740     //                                it deletes the playwindow that has been set
       
   741     iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64()/1000);
       
   742     if (aStart == iSavedSetPosition)
       
   743         {
       
   744         return;
       
   745         }
       
   746 	switch (iState)
       
   747 		{
       
   748 		case EStopped:  // no need to do anything with start position since the start position is saved
       
   749 			// iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64()/1000);
       
   750 			// break;
       
   751 		case EInitializing: // if already primed or priming, we need to get to correct start position
       
   752 		case EInitialized:
       
   753 			// DoSetPositionL(iInitPosition);
       
   754 			// iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64()/1000);
       
   755             SetPositionL(iPlayWindowStartPosition);
       
   756 			break;
       
   757 		case EPlaying:
       
   758 		case EPaused:
       
   759 		case EAutoPaused:
       
   760 		    // If the Playwindow start position is greater than the current position
       
   761 		    // then we seek to the new position and start playing from there.
       
   762 		    if ( iPlayWindowEndPosition != TTimeIntervalMicroSeconds(0) )
       
   763 		        {
       
   764 		        TTimeIntervalMicroSeconds currentPosition = PositionL();
       
   765                 if ( currentPosition < iPlayWindowStartPosition )
       
   766                     {
       
   767                     SetPositionL(iPlayWindowStartPosition);
       
   768                     }
       
   769 		        }
       
   770 			break;
       
   771         default:
       
   772             Panic(EBadState);
       
   773             break;
       
   774  		}
       
   775     
       
   776     }
       
   777     
       
   778 // -----------------------------------------------------------------------------
       
   779 // CAdvancedAudioPlayController::AddDataSourceL
       
   780 // -----------------------------------------------------------------------------
       
   781 //
       
   782 EXPORT_C void CAdvancedAudioPlayController::AddDataSourceL(
       
   783     MDataSource& aSource)
       
   784     {
       
   785     DP1(_L("CAdvancedAudioPlayController::AddDataSourceL this[%x]"), this);
       
   786     iSourceUnreadable = EFalse;
       
   787     iEnablePrimedStateChangedEvent = EFalse;
       
   788     // source type is intended to not be needed by controllers
       
   789     // but metadata functions still use it
       
   790     iSourceType = aSource.DataSourceType();
       
   791     iBitRateFrozen = EFalse;
       
   792     iDurationFrozen = EFalse;
       
   793     if (iWait)
       
   794         {
       
   795         iWait->AsyncStop();
       
   796         }
       
   797     if (iDataSourceAdapter)
       
   798 		{
       
   799         User::Leave(KErrAlreadyExists);
       
   800         }
       
   801     if (iSharedBufferMaxNum <= 2)
       
   802         {
       
   803         iSharedBufferMaxNum = 3;
       
   804         }
       
   805 
       
   806 
       
   807 	// set iReadHeader here in case prime is not called before set position is used.
       
   808     // reset before adding data source
       
   809     DP0(_L("CAdvancedAudioPlayController::AddDataSourceL reseting iSharedBufferCnt iReadHeader iInitPosition position vars"));
       
   810     iSharedBufferCnt = 0;
       
   811 	iReadHeader = ETrue;
       
   812 	iInitPosition = -1;
       
   813 	ResetPositionVariables();
       
   814 
       
   815 	DoAddDataSourceL();
       
   816 
       
   817 	if (!iDataSourceAdapter)
       
   818 		{
       
   819 		iDataSourceAdapter = CDataSourceAdapter::NewL();
       
   820 		}
       
   821 	iDataSourceAdapter->SetDataSourceL(&aSource, this, this);
       
   822 	
       
   823     iDataSource = &aSource; // remove this eventually when all the references are removed
       
   824 	
       
   825 	iSourceIsTimeSeekable = iDataSourceAdapter->IsTimeSeekable();
       
   826 	iSourceIsPosSeekable = iDataSourceAdapter->IsPositonSeekable();
       
   827 	
       
   828    	if (iDataSourceAdapter->IsProtectedL())
       
   829         {
       
   830 		if (iDataSink && iDataSink->DataSinkType() == KUidMmfFileSink)
       
   831 			{
       
   832 			// Conversion is not allowed for DRM protected files
       
   833 			User::Leave(KErrNotSupported);
       
   834 			}
       
   835         }
       
   836 
       
   837     iDataSourceAdapter->SetSourcePrioritySettings(iPrioritySettings);
       
   838     
       
   839     if (iAudioUtility)
       
   840         { // 3gp would not have utility built yet
       
   841         iAudioUtility->SetObserver(*this);
       
   842         }
       
   843 
       
   844     // we need to block this until duration is calculated if using mmfplayutility
       
   845     iBlockDuration = EFalse;
       
   846     
       
   847     if ((!iEventsEnabled) && (!iDataSourceAdapter->OnlyHeaderPresent()))
       
   848         {
       
   849         // recorder inserts just the header into the file before recording
       
   850         // we don't want to prime in this case
       
   851         DP0(_L("CAdvancedAudioPlayController::AddDataSourceL() Prime to get duration"));
       
   852         iBlockDuration = ETrue;
       
   853         DoInitializeL(); // to get data from the source to calculate bitrate and duration
       
   854         }
       
   855     if ((!iEventsEnabled) && (iDataSourceAdapter->OnlyHeaderPresent()))
       
   856         {
       
   857         // this is a file being recorded.
       
   858         // the recorder might have to open this file again - and if we keep it open
       
   859         // with shared read access, he won't be able to open it for writing.
       
   860         // So we will close the file here.
       
   861         iDataSourceAdapter->SourceStopL();
       
   862         }
       
   863     }
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // CAdvancedAudioPlayController::DurationL
       
   867 // 
       
   868 // -----------------------------------------------------------------------------
       
   869 //
       
   870 EXPORT_C TTimeIntervalMicroSeconds CAdvancedAudioPlayController::DurationL() const
       
   871     {
       
   872 	DP2(_L("CAdvancedAudioController::DurationL this[%x] iDuration[%d]"), this, iDuration);
       
   873     // we need to block this until duration is calculated if using mmfplayutility
       
   874     if (iBlockDuration)
       
   875         {
       
   876         iBlockDuration = EFalse;
       
   877         iWait = new (ELeave) CActiveSchedulerWait();
       
   878         DP0(_L("CAdvancedAudioController::DurationL() blocking for duration"));
       
   879         iWait->Start();
       
   880         DP0(_L("CAdvancedAudioController::DurationL() continuing"));
       
   881         delete iWait;
       
   882         iWait = NULL;
       
   883         }
       
   884     return TTimeIntervalMicroSeconds(iDuration);
       
   885     }
       
   886 
       
   887 
       
   888 // -----------------------------------------------------------------------------
       
   889 // CAdvancedAudioPlayController::AddDataSinkL
       
   890 // -----------------------------------------------------------------------------
       
   891 //
       
   892 EXPORT_C void CAdvancedAudioPlayController::AddDataSinkL(
       
   893     MDataSink& aSink)
       
   894     {
       
   895     DP1(_L("CAdvancedAudioPlayController::AddDataSinkL this[%x]"), this);
       
   896 
       
   897 //	TThreadStackInfo info;
       
   898 //	RThread().StackInfo(info);
       
   899 //    DP1(_L("### Stack Base Address: [0x%x]"), info.iBase);
       
   900 //    DP1(_L("### Stack End  Address: [0x%x]"), info.iLimit);
       
   901     
       
   902     if (iDataSink)
       
   903         {
       
   904         User::Leave(KErrAlreadyExists);
       
   905         }
       
   906 
       
   907     if (aSink.DataSinkType() == KUidMmfAudioOutput)
       
   908         {
       
   909 		iDataSink = &aSink;
       
   910         }
       
   911     else if (aSink.DataSinkType() == KUidMmfFileSink)
       
   912         { // only use of source type here other than metadata functions
       
   913 		if (iDataSource && iSourceType == KUidMmfFileSource)
       
   914 			{
       
   915 			CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   916 			file->SourcePrimeL();
       
   917 			
       
   918 			if (file->IsProtectedL())
       
   919 				{
       
   920 				// Conversion is not allowed for DRM protected files
       
   921 				User::Leave(KErrNotSupported);
       
   922 				}
       
   923 			}
       
   924 			
       
   925         iDataSink = &aSink;
       
   926         iDataSink->SinkPrimeL();
       
   927         iDataSink->SinkThreadLogon(*this);
       
   928 		iDriveNumber = iAudioUtility->GetDriveNumber(static_cast<CMMFFile*>(iDataSink)->FileDrive());
       
   929 		}
       
   930     else
       
   931         {
       
   932         User::Leave(KErrNotSupported);
       
   933         }
       
   934 	DoAddDataSinkL(); // iAudioOutput will be created here
       
   935 	// if the source has already been added but the output has not been configured because the sink was
       
   936 	// not ready, then we will configure the output here.
       
   937 	if (iSinkInitDataReady)
       
   938 		{
       
   939 		DoInitializeSinkL(); // the decoder will be created here
       
   940 		}
       
   941     }
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CAdvancedAudioPlayController::RemoveDataSourceL
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 EXPORT_C void CAdvancedAudioPlayController::RemoveDataSourceL(
       
   948     MDataSource& aDataSource)
       
   949     {
       
   950     DP0(_L("CAdvancedAudioPlayController::RemoveDataSourceL"));
       
   951 
       
   952     if (!iDataSource)
       
   953 		{
       
   954         User::Leave(KErrNotReady);
       
   955 		}
       
   956 
       
   957     if (iDataSource != &aDataSource)
       
   958 		{
       
   959         User::Leave(KErrArgument);
       
   960 		}
       
   961 
       
   962     if ((iState != EStopped) && (iState != EInitialized))
       
   963 		{
       
   964         User::Leave(KErrNotReady);
       
   965 		}
       
   966 
       
   967     iDataSource->SourceStopL();     // should always stop source before logoff
       
   968 	iDataSource->SourceThreadLogoff();
       
   969     
       
   970 	MapcDeletePlaybackWindowL();
       
   971 
       
   972     if (iIsDRMProtected)
       
   973 		{
       
   974 		delete iDataSource;
       
   975 		}
       
   976 	iDataSource = NULL;
       
   977 	delete iDataSourceAdapter;
       
   978 	iDataSourceAdapter = NULL;
       
   979 	iSinkInitDataReady = EFalse;
       
   980     }
       
   981 
       
   982 // -----------------------------------------------------------------------------
       
   983 // CAdvancedAudioPlayController::RemoveDataSinkL
       
   984 // -----------------------------------------------------------------------------
       
   985 //
       
   986 EXPORT_C void CAdvancedAudioPlayController::RemoveDataSinkL(
       
   987     MDataSink& aDataSink)
       
   988     {
       
   989     DP0(_L("CAdvancedAudioPlayController::RemoveDataSinkL"));
       
   990 
       
   991     if (!iDataSink)
       
   992 		{
       
   993         User::Leave(KErrNotReady);
       
   994 		}
       
   995 
       
   996     if (iDataSink != &aDataSink)
       
   997 		{
       
   998         User::Leave(KErrArgument);
       
   999 		}
       
  1000 
       
  1001     if ((iState != EStopped) && (iState != EInitialized))
       
  1002 		{
       
  1003         User::Leave(KErrNotReady);
       
  1004 		}
       
  1005 
       
  1006     iDataSink->SinkStopL();         // should always stop source before logoff
       
  1007 	iDataSink->SinkThreadLogoff();
       
  1008 
       
  1009     // dereference Decoder from Utility before deleting AudioOutput (which took ownership of decoder)
       
  1010     if (iAudioUtility)
       
  1011     	{
       
  1012         iAudioUtility->DeReferenceDecoder();
       
  1013     	}
       
  1014     
       
  1015 	delete iAudioOutput;
       
  1016 	iAudioOutput = NULL;
       
  1017     iDataSink = NULL;
       
  1018     iDecoderExists = EFalse;
       
  1019     }
       
  1020 
       
  1021 // -----------------------------------------------------------------------------
       
  1022 // CAdvancedAudioPlayController::ResetL
       
  1023 // -----------------------------------------------------------------------------
       
  1024 //
       
  1025 EXPORT_C void CAdvancedAudioPlayController::ResetL()
       
  1026     {
       
  1027     DP0(_L("CAdvancedAudioPlayController::ResetL"));
       
  1028 
       
  1029     RemoveDataSourceL(*iDataSource);
       
  1030     RemoveDataSinkL(*iDataSink);
       
  1031     }
       
  1032 
       
  1033 // -----------------------------------------------------------------------------
       
  1034 // CAdvancedAudioPlayController::PrimeL
       
  1035 // -----------------------------------------------------------------------------
       
  1036 //
       
  1037 EXPORT_C void CAdvancedAudioPlayController::PrimeL()
       
  1038     { // this is for user call only - this changes the request state 
       
  1039 	DP2(_L("CAdvancedAudioPlayController::PrimeL this[%x] iState[%d]"), this, iState);
       
  1040 
       
  1041 	switch (iState)
       
  1042 		{
       
  1043 		case EStopped:
       
  1044 			iRequestState = EInitialized;
       
  1045 			iEnablePrimedStateChangedEvent = ETrue;
       
  1046 			DoInitializeL();
       
  1047 			break;
       
  1048 		case EInitializing: // we may already be initializing since we may doinitialize to get header info for mmf client-events disabled)
       
  1049             iRequestState = EInitialized;
       
  1050             iEnablePrimedStateChangedEvent = ETrue;
       
  1051 		    break;
       
  1052 		case EInitialized:
       
  1053             iRequestState = EInitialized;
       
  1054             iEnablePrimedStateChangedEvent = ETrue;
       
  1055             if (AllBuffersFilled())
       
  1056                 {
       
  1057                 iEnablePrimedStateChangedEvent = EFalse;
       
  1058                 DP0(_L("CAdvancedAudioPlayController::PrimeL state changed primed"));
       
  1059                 SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPrimed, KErrNone)); // both source and sink are ready.
       
  1060                 }
       
  1061             break;
       
  1062 		case EPlaying:
       
  1063 		case EPaused:
       
  1064 		case EAutoPaused:
       
  1065 			break;
       
  1066         default:
       
  1067             Panic(EBadState);
       
  1068             break;
       
  1069  		}
       
  1070     }
       
  1071 
       
  1072 void CAdvancedAudioPlayController::DoInitializeL()
       
  1073 	{ // this is the DoPrimeL
       
  1074 	DP1(_L("CAdvancedAudioPlayController::DoInitializeL this[%x]"), this);
       
  1075     
       
  1076 	if (iSourceUnreadable)
       
  1077         {
       
  1078         DP0(_L("CAdvancedAudioPlayController::PrimeL KErrCorrupt"));
       
  1079         User::Leave(KErrCorrupt);
       
  1080         }
       
  1081 
       
  1082 	if (iDataSourceAdapter)
       
  1083 		{
       
  1084 		iState = EInitializing;
       
  1085 		if (iAudioUtility)
       
  1086 			{ // 3gp won't have a utility yet
       
  1087 			TInt err = iAudioUtility->ResetTable();
       
  1088 			}	
       
  1089 		iDataSourceAdapter->SourcePrimeL();    // get the source ready to process data
       
  1090 		iDataSourceAdapter->SourcePlayL();     // get the source ready to send data
       
  1091 		InitSharedBuffersL();
       
  1092 		// The position variables are reset when primed.
       
  1093 		// We don't want to reset them during stop because time needs to be maintained
       
  1094 		// in case position is called after stopping.
       
  1095 		ResetPositionVariables();
       
  1096 		}
       
  1097     }
       
  1098 
       
  1099 
       
  1100 // -----------------------------------------------------------------------------
       
  1101 // CAdvancedAudioPlayController::PlayL
       
  1102 // -----------------------------------------------------------------------------
       
  1103 //
       
  1104 EXPORT_C void CAdvancedAudioPlayController::PlayL()
       
  1105     { // this is for user call only - this changes the request state 
       
  1106 	DP5(_L("CAdvancedAudioPlayController::PlayL this[%x] iCurrentPosition[%d] iSourceReadPosition[%d] iState[%d] iRequestState[%d]"),
       
  1107 		this, iCurrentPosition, iSourceReadPosition, iState, iRequestState);
       
  1108 	if (iSourceUnreadable)
       
  1109 	    {
       
  1110         SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrCorrupt));
       
  1111         SendEventToClient(TMMFEvent(KStreamControlEventStateChangedStopped, KErrCorrupt));
       
  1112         return;
       
  1113 	    }
       
  1114 	if (iRequestState == EPlaying)
       
  1115 		{
       
  1116 		return;
       
  1117 		}
       
  1118 	if (iPlayingForDuration || iPlayingForPauseSeek || iPlayingForInitPos)
       
  1119 		{ 
       
  1120 		// PlayForDuration is not used.
       
  1121 		// Internally we use DoPlayL().
       
  1122 		// Just save the request and return, we don't want to call doplay again here.
       
  1123 	 	// User has overridden reason for play - we don't want to transition back to old state now.
       
  1124 		// iPlayingForDuration, iPlayingForPauseSeek, and iPlayingForInitPos will 
       
  1125 		// be reset when the current seek is complete.
       
  1126 		// Already playing internally so send state change
       
  1127 		iRequestState = EPlaying;
       
  1128 	    SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPlaying, KErrNone));
       
  1129 		return;
       
  1130 		}
       
  1131 	switch (iState)
       
  1132 		{
       
  1133 		case EStopped:
       
  1134 			// don't initialize playback with DoInitialize() here
       
  1135 			//  because latent play calls would get through after stops - seek to eof and play
       
  1136 		    //  also, latent play calls would get through after pausing just after eof reached and controller stops.
       
  1137 		    DP1(_L("CAdvancedAudioPlayController::PlayL iState=EStopped and iRequestState[%d]"), iRequestState);
       
  1138 			if ((iRequestState == EInitialized) || (iRequestState == EPaused))
       
  1139 				{ // primed state requested, but will stop if eof
       
  1140 				SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrNone));
       
  1141 				}
       
  1142 			break;
       
  1143 		case EInitializing: // priming
       
  1144 			iRequestState = EPlaying;
       
  1145 			break;
       
  1146 		case EInitialized: // primed
       
  1147 			iRequestState = EPlaying;
       
  1148 	        if (iPlayWindowEndPosition > 0)
       
  1149 	            {
       
  1150 	            DP1(_L("CAdvancedAudioPlayController::PlayL iAudioUtility->SetPlayWindowEndTimeMs(%d)"), I64LOW(iPlayWindowEndPosition.Int64()/1000));
       
  1151 	            iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64() / 1000);
       
  1152 	            }
       
  1153             if (iAudioOutput->IsDSStopped())
       
  1154                 { // during loop play the output is not stopped unless we did a seek - seek stops the output and we need to call DoPlay
       
  1155                 DP0(_L("CAdvancedAudioPlayController::PlayL Calling DoPlay iState=EInitialized and iRequestState=EPlaying"));
       
  1156                 DoPlayL();
       
  1157                 }
       
  1158             else
       
  1159                 {
       
  1160                 DP1(_L("CAdvancedAudioPlayController::PlayL Calling DoResume iState=EInitialized iCurrentPosition[%d]"), iCurrentPosition);
       
  1161                 if (IsLoopPlayEnabled())
       
  1162                     {
       
  1163                     DoResume(iCurrentPosition); // sends state change event if successful
       
  1164                     }
       
  1165                 else
       
  1166                     {
       
  1167                     DoPlayL();
       
  1168                     }
       
  1169                 }
       
  1170 			break;
       
  1171 		case EPlaying:
       
  1172 			break;
       
  1173 		case EPaused:
       
  1174 			iRequestState = EPlaying;
       
  1175 	        if (iPlayWindowEndPosition > 0)
       
  1176 	            {
       
  1177 	            DP1(_L("CAdvancedAudioPlayController::PlayL iAudioUtility->SetPlayWindowEndTimeMs(%d)"), I64LOW(iPlayWindowEndPosition.Int64()/1000));
       
  1178 	            iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64() / 1000);
       
  1179 	            }
       
  1180             if (iAudioOutput->IsDSStopped())
       
  1181                 { // during loop play the output is not stopped unless we did a seek - seek stops the output and we need to call DoPlay
       
  1182                 DP0(_L("CAdvancedAudioPlayController::PlayL Calling DoPlay iState=EPaused"));
       
  1183                 DoPlayL();
       
  1184                 }
       
  1185             else
       
  1186                 {
       
  1187                 DP1(_L("CAdvancedAudioPlayController::PlayL Calling DoResume iState=EPaused iCurrentPosition[%d]"), iCurrentPosition);
       
  1188                 if (IsLoopPlayEnabled())
       
  1189                     {
       
  1190                     DoResume(iCurrentPosition);
       
  1191                     }
       
  1192                 else
       
  1193                     {
       
  1194                     DoPlayL();
       
  1195                     }
       
  1196                 }
       
  1197 			break;
       
  1198 		case EAutoPaused:
       
  1199 			break;
       
  1200         default:
       
  1201             Panic(EBadState);
       
  1202             break;
       
  1203  		}
       
  1204 
       
  1205 //    SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPlaying, KErrNone));
       
  1206 	}
       
  1207 
       
  1208 
       
  1209 void CAdvancedAudioPlayController::DoPlayL()
       
  1210 	{
       
  1211 	DP2(_L("CAdvancedAudioPlayController::DoPlayL reqstate[%d] pfps[%d]"),iRequestState,iPlayingForPauseSeek);
       
  1212     if ((iRequestState == EPlaying) || iPlayingForInitPos || iPlayingForDuration || iPlayingForPauseSeek)
       
  1213         {
       
  1214 		if (AllBuffersFilled()) // state entry condition
       
  1215 			{ // DoSetPositionL will look in shared buffers first and not seek if found
       
  1216 			// we may consider to use the current time here and resolve current position here instead of other places in the code
       
  1217 
       
  1218 			if (iCurrentPosition == KMaxTUint)
       
  1219                 { // in case of a time seekable source, we use KMaxTUint in the seek since we don't know source position
       
  1220                 DP0(_L("CAdvancedAudioPlayController::DoPlayL Resetting iCurrentPosition to zero"));
       
  1221                 iCurrentPosition = 0;
       
  1222 			    }
       
  1223 
       
  1224 			iSharedBufferIndex = FindBufferFromPos(iCurrentPosition);
       
  1225 		
       
  1226 			// if there was seek past end of file, the buffers may not have any data
       
  1227 			// they may all be empty last buffers
       
  1228 			if ((iSharedBufferIndex < 0) and AllBuffersEmpty())
       
  1229 			    { // position in buffer not found
       
  1230 			    DoStopL(KErrNone);
       
  1231 			    return;
       
  1232 			    }
       
  1233 			if (iSharedBufferIndex < 0)
       
  1234 			    {
       
  1235 			    DoStopL(KErrGeneral);
       
  1236 		    	return;
       
  1237 			    }
       
  1238 		
       
  1239 	    	if (iDataSink->DataSinkType() == KUidMmfFileSink)
       
  1240     	    	{
       
  1241 	    	    static_cast<CMMFClip*>(iDataSink)->SinkPrimeL();
       
  1242 	    	    static_cast<CMMFFile*>(iDataSink)->FileL().SetSize(0); // Reset output file
       
  1243     	    	}
       
  1244 
       
  1245             // if client has called Play() again, then we need to set the repeats so that the loop play can go on.
       
  1246             // this must be done only when all the repeats are done and when the play back has stopped after the repeats
       
  1247             // if client issues a play after the loop play, we must retain the repeat count and start the loop play again.
       
  1248             // if play was called during loop play it must be ignored and loop play should continue
       
  1249             if ((!iLoopPlayEnabled) && ((iRepeatCount > 0) || (iRepeatCount == KMdaRepeatForever)))
       
  1250                 {
       
  1251                 if ((iTrailingSilenceTimer) && (iTrailingSilenceTimer->IsActive()))
       
  1252                     iTrailingSilenceTimer->Cancel();
       
  1253                     DoSetRepeats(iRepeatCount, TTimeIntervalMicroSeconds(iTrailingSilenceMs.Int()));
       
  1254                 }
       
  1255 			TInt errExIntent = KErrNone;
       
  1256 			if (!iDisableAutoIntent && (iRequestState == EPlaying))
       
  1257 				{
       
  1258                 if (iIntentStopped)
       
  1259                     {
       
  1260                     errExIntent = iDataSourceAdapter->EvaluateIntent(ContentAccess::EPlay);
       
  1261                     if (errExIntent == KErrNone)
       
  1262                         {
       
  1263                         errExIntent = iDataSourceAdapter->ExecuteIntent(ContentAccess::EPlay);
       
  1264                         DP2(_L("CAdvancedAudioPlayController::DoPlayL() iIntentStopped[%d] errExIntent[%d]"), iIntentStopped, errExIntent );
       
  1265                         if (errExIntent == KErrNone)
       
  1266                             iIntentStopped = EFalse;
       
  1267                         }
       
  1268                     else // if ((errExIntent == KErrKErrNoRights) || any other error)
       
  1269                         {
       
  1270                         DoStopL(errExIntent);
       
  1271                         return;
       
  1272                         }
       
  1273                     }
       
  1274                 else
       
  1275                     {
       
  1276                     errExIntent = iDataSourceAdapter->EvaluateIntent((iState == EPaused) ? ContentAccess::EContinue : ContentAccess::EPlay);
       
  1277                     if (errExIntent == KErrNone)
       
  1278                         {
       
  1279                         errExIntent = iDataSourceAdapter->ExecuteIntent((iState == EPaused) ? ContentAccess::EContinue : ContentAccess::EPlay);
       
  1280                         DP2(_L("CAdvancedAudioPlayController::DoPlayL() iIntentStopped[%d] errExIntent[%d]"), iIntentStopped, errExIntent );
       
  1281                         }
       
  1282                     else // if ((errExIntent == KErrKErrNoRights) || any other error)
       
  1283                         {
       
  1284                         DoStopL(errExIntent);
       
  1285                         return;
       
  1286                         }
       
  1287                     }
       
  1288                 }
       
  1289 			if ((errExIntent != KErrNone) && (errExIntent != KErrNotSupported))
       
  1290 				{
       
  1291                 DP1(_L("CAdvancedAudioPlayController::DoPlayL() errExIntent[%d]"), errExIntent);
       
  1292                 // const TInt KErrCANoRights = -17452;  from caferr.h
       
  1293                 // don't leave because, stopping the source above will delete this active object..
       
  1294                 // the active scheduler will try to call runerror on the active object, but it's gone.
       
  1295                 //User::Leave(errExIntent);
       
  1296                 return;
       
  1297                 }
       
  1298 			iState = EPlaying; // stay in initialized state so bufferfilled will continue to call doplay
       
  1299 			iResumePosition = -1;
       
  1300 			iAudioOutput->PlayL(&iSharedBuffers, iSharedBufferIndex);
       
  1301             SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPlaying, KErrNone));
       
  1302 			}
       
  1303         }
       
  1304     }
       
  1305 
       
  1306 // -----------------------------------------------------------------------------
       
  1307 // CAdvancedAudioPlayController::PauseL
       
  1308 // -----------------------------------------------------------------------------
       
  1309 //
       
  1310 EXPORT_C void CAdvancedAudioPlayController::PauseL()
       
  1311     { // this is for user call only - this changes the request state 
       
  1312 	DP2(_L("CAdvancedAudioPlayController::PauseL this[%x] iState[%d]"), this, iState);
       
  1313 	if (iRequestState == EPaused)
       
  1314 		{
       
  1315 		return;
       
  1316 		}
       
  1317 	iRequestState = EPaused;
       
  1318 
       
  1319     switch (iState)
       
  1320         {
       
  1321         case EStopped:
       
  1322         case EInitializing:
       
  1323         case EInitialized:
       
  1324         	break;
       
  1325         case EAutoPaused:
       
  1326         case EPlaying: // pause even if we are playing for seeking so state change will occur
       
  1327 			DoPauseL(); // the pause will set position correctly
       
  1328             SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPaused, KErrNone));
       
  1329         	break;
       
  1330         case EPaused:
       
  1331         	break;
       
  1332         default:
       
  1333             Panic(EBadState);
       
  1334             break;
       
  1335         }
       
  1336 //    SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPaused, KErrNone));
       
  1337     }
       
  1338 
       
  1339 void CAdvancedAudioPlayController::DoPauseL(TBool aPreemption)
       
  1340 	{
       
  1341    	DP5(_L("CAdvancedAudioPlayController::DoPauseL pfsp[%d] pfip[%d] pfps[%d] pfd[%d] rqststate[%d]"),
       
  1342     	    iPausingForSetPos, iPlayingForInitPos, iPlayingForPauseSeek, iPlayingForDuration, iRequestState);
       
  1343 //    if ((iPausingForSetPos || iPlayingForInitPos || iPlayingForPauseSeek || iPlayingForDuration) && 
       
  1344 //        (iRequestState != EPaused)) // seek position reached and returning to pause state automatically
       
  1345    	// both user pause and internal pause come here.
       
  1346    	// Internal pause may be from preemption or seek position reached.
       
  1347    	/*
       
  1348    	 * Pre-emption case: Pause during a pre-emption and not seeking
       
  1349    	 */
       
  1350     if ((iPlayingForInitPos || iPlayingForPauseSeek || iPausingForSetPos) && aPreemption)
       
  1351         {// we got preempted during a seek
       
  1352         // we're already seeking to a position. When we get there we'll come here again, but handle it below
       
  1353         DP0(_L("CAdvancedAudioPlayController::DoPauseL got a preemption during seek"));
       
  1354         return;
       
  1355         }
       
  1356 
       
  1357     /*
       
  1358      * Internal Pause case: Pausing during an internal seeking and not pre-emption case.
       
  1359      */
       
  1360       if ((iPlayingForInitPos || iPlayingForPauseSeek || iPausingForSetPos) && !aPreemption)
       
  1361         { // already seeking to position, so we don't want to set position again
       
  1362     	DP0(_L("CAdvancedAudioPlayController::DoPauseL not setting pos because we are already seeking"));
       
  1363         if (IsLoopPlayEnabled())
       
  1364             {
       
  1365             DP0(_L("CAdvancedAudioPlayController::DoPauseL AudioOutput->StopL(EFalse)"));
       
  1366             // If in LoopPlay mode, DO NOT STOP the Devsound from AudioOutput
       
  1367             iAudioOutput->StopL(EFalse);
       
  1368             }
       
  1369         else
       
  1370             {
       
  1371             // If in normal Play mode, Devsound can be stopped during Pause
       
  1372             // StopL method takes the default value as ETrue, so we don't need to pass any value.
       
  1373 
       
  1374             // if we are seeking, we need to flush the devsound buffers regardless of loop play
       
  1375             DP0(_L("CAdvancedAudioPlayController::DoPauseL AudioOutput->StopL()"));
       
  1376             iAudioOutput->StopL();
       
  1377             }
       
  1378         if (iPlayingForInitPos)
       
  1379             {
       
  1380             iState = EInitialized;
       
  1381             }
       
  1382         else
       
  1383             {
       
  1384             iState = EPaused;
       
  1385             }
       
  1386 	    iPlayingForPauseSeek = EFalse;
       
  1387     	iPlayingForInitPos = EFalse;
       
  1388     	// iPausingForSetPos is cleared when seekposition reached
       
  1389     	// iPlayingForDuration is cleared in stop which is where seekposreached sends it
       
  1390 		TInt foundPosition;
       
  1391 		TInt foundTimeMs;
       
  1392 		TUint time = iTimePositionInMicroSecs/1000; // time was set at the seek so it would be correct after seek.
       
  1393         DP1(_L("CAdvancedAudioPlayController::DoPauseL iTimePositionInMicroSecs[%u]"),iTimePositionInMicroSecs);
       
  1394 		// this set position is short version because we expect that we have the buffer available after the seek.
       
  1395 		// since we are not setting position as below, we can get the buffer ready for play.
       
  1396 	    TInt err = SetPositionInSharedBuffers(time, foundPosition, foundTimeMs);
       
  1397 	    iCurrentPosition = foundPosition;
       
  1398 	    iTimePositionInMicroSecs = foundTimeMs; // just to get exact to position
       
  1399 	    iTimePositionInMicroSecs *=1000;
       
  1400         DP1(_L("CAdvancedAudioPlayController::DoPauseL iCurrentPosition[%d]"),iCurrentPosition);
       
  1401 	    DP1(_L("CAdvancedAudioPlayController::DoPauseL iTimePositionInMicroSecs[%u]"),foundTimeMs);
       
  1402 	    // setpositioninsharedbuffers can reposition, so we need to update the ref
       
  1403 		iAudioUtility->SetSourceReference(foundTimeMs, iCurrentPosition-iHeaderOffset-iSyncOffset);
       
  1404 
       
  1405 	    RefillPreceedingBuffersL();
       
  1406 	    
       
  1407         return;
       
  1408         }
       
  1409 
       
  1410       /*
       
  1411        * User Pause case: User Pause when TruePause is not supported by DevSound adaptation (not seeking and not pre-emption)
       
  1412        */
       
  1413 	// if user interrupts pause, don't mess with the time since it was already set at the seek
       
  1414 	// and the position will end up getting set to that time below.
       
  1415 	if (iPlayingForInitPos || iPlayingForPauseSeek)
       
  1416 		{
       
  1417 		DP2(_L("CAdvancedAudioPlayController::DoPauseL UserPause pfip[%d] pfps[%d]"),iPlayingForInitPos,  iPlayingForPauseSeek);
       
  1418 	    iPlayingForPauseSeek = EFalse;
       
  1419     	iPlayingForInitPos = EFalse;
       
  1420 		}
       
  1421 	else
       
  1422 		{
       
  1423         DP1(_L("CAdvancedAudioPlayController::DoPauseL UserPause before calc iTimePositionInMicroSecs [%d]"), iTimePositionInMicroSecs);
       
  1424         // during loop play devsound returns the incremented value of the position
       
  1425         // it must be adjusted to the duration of the audio clip so that playback can resume from the position where it was paused
       
  1426         if (IsLoopPlayEnabled())
       
  1427             {
       
  1428             iTimePositionInMicroSecs += (iAudioOutput->CalculateAudioOutputPositionL() - iSavedTimePositionInMicroSecs);
       
  1429             }
       
  1430         else
       
  1431             {
       
  1432             iTimePositionInMicroSecs += iAudioOutput->CalculateAudioOutputPositionL();
       
  1433             }
       
  1434         DP1(_L("CAdvancedAudioPlayController::DoPauseL UserPause after calc iTimePositionInMicroSecs [%d]"), iTimePositionInMicroSecs);
       
  1435         }
       
  1436 
       
  1437 	// in case of client pause, stop the trailing silence timer during loop play and stay in paused state.
       
  1438     // controller goes to play state when client calls play
       
  1439     if ((iTrailingSilenceTimer) && (iTrailingSilenceTimer->IsActive()))
       
  1440         {
       
  1441         DP0(_L("CAdvancedAudioPlayController::DoPauseL UserPause Cancelling the TrailingSilenceTimer for User Pause "));
       
  1442         iTrailingSilenceTimer->Cancel();
       
  1443         }
       
  1444 
       
  1445     TInt errExIntent = KErrNone;
       
  1446     if (!iDisableAutoIntent)
       
  1447         {
       
  1448         errExIntent = iDataSourceAdapter->EvaluateIntent(ContentAccess::EPause);
       
  1449         if (errExIntent == KErrNone)
       
  1450             {    
       
  1451             errExIntent = iDataSourceAdapter->ExecuteIntent(ContentAccess::EPause);
       
  1452             }
       
  1453         }
       
  1454 
       
  1455     if (IsLoopPlayEnabled())
       
  1456         {
       
  1457         DP0(_L("CAdvancedAudioPlayController::DoPauseL UserPause AudioOutput->StopL(EFalse)"));
       
  1458         // if in LoopPlay mode, DO NOT STOP the Devsound during a pause operation since we resume the playback from the paused position
       
  1459         iAudioOutput->StopL(EFalse);
       
  1460         }
       
  1461     else
       
  1462         {
       
  1463         // If in normal Play mode, Devsound can be stopped during Pause
       
  1464         // StopL method takes the default value as ETrue, so we don't need to pass any value.
       
  1465         DP0(_L("CAdvancedAudioPlayController::DoPauseL UserPause AudioOutput->StopL()"));
       
  1466         iAudioOutput->StopL();
       
  1467         }
       
  1468 	iState = EPaused;
       
  1469     DoSetPositionL(TTimeIntervalMicroSeconds(iTimePositionInMicroSecs)); // if we were play seeking, this will reseek to desired position
       
  1470 
       
  1471 	if ((errExIntent != KErrNone) && (errExIntent != KErrNotSupported))
       
  1472 		{
       
  1473         // User::Leave(errExIntent);
       
  1474         return;
       
  1475 		}
       
  1476 	}
       
  1477 	
       
  1478 // -----------------------------------------------------------------------------
       
  1479 // CAdvancedAudioPlayController::StopL
       
  1480 // -----------------------------------------------------------------------------
       
  1481 //
       
  1482 EXPORT_C void CAdvancedAudioPlayController::StopL()
       
  1483     { // this is for user call only - this changes the request state 
       
  1484 	DP2(_L("CAdvancedAudioPlayController::StopL this[%x] iState[%d]"), this, iState);
       
  1485 	if (iRequestState == EStopped)
       
  1486 		{
       
  1487 		return;
       
  1488 		}
       
  1489    	iRequestState = EStopped;
       
  1490     switch (iState)
       
  1491         {
       
  1492         case EStopped:
       
  1493         	break;
       
  1494         case EInitializing:
       
  1495         case EInitialized:
       
  1496         case EPlaying:
       
  1497         case EPaused:
       
  1498         case EAutoPaused:
       
  1499             TRAP_IGNORE(DoStopL(KErrNone));     // ignore if any leave to ensure internal state change on the next statement
       
  1500     	    break;
       
  1501         default:
       
  1502             Panic(EBadState);
       
  1503             break;
       
  1504         }
       
  1505     // user event    
       
  1506 	
       
  1507 	SendEventToClient(TMMFEvent(KStreamControlEventStateChangedStopped, KErrNone));
       
  1508     }
       
  1509     
       
  1510 // -----------------------------------------------------------------------------
       
  1511 // CAdvancedAudioPlayController::DoStopL
       
  1512 // -----------------------------------------------------------------------------
       
  1513 //
       
  1514 EXPORT_C void CAdvancedAudioPlayController::DoStopL(TInt aError)
       
  1515     {
       
  1516 	DP3(_L("CAdvancedAudioPlayController::DoStopL this[%x] iState[%d], aError[%d]"), this, iState, aError);
       
  1517     DP0(_L("CAdvancedAudioPlayController::DoStopL reseting iInitPosition iReadHeader"));
       
  1518 	CleanupForStop();
       
  1519 	// If the playwindow is still active (iPlayWindowEndPosition > 0)
       
  1520 	// then set the current playback position to play window start position
       
  1521 	// If there is a client Stop() call or End of playback event then we need to check for the
       
  1522 	// playwindow start position.
       
  1523 	if (iPlayWindowEndPosition > 0)
       
  1524 	    {
       
  1525 	    iInitPosition = iPlayWindowStartPosition;
       
  1526 	    }
       
  1527 	else
       
  1528 	    {
       
  1529 	    iInitPosition = -1;
       
  1530 	    }
       
  1531     if (iTrailingSilenceTimer)
       
  1532         {
       
  1533         delete iTrailingSilenceTimer;
       
  1534         iTrailingSilenceTimer = NULL;
       
  1535         }
       
  1536 	iReadHeader = ETrue;
       
  1537     iEnablePrimedStateChangedEvent = EFalse;
       
  1538     iSharedBufferCnt = 0;
       
  1539     if (iAudioOutput)
       
  1540 		{
       
  1541         // during loop play devsound returns the incremented value of the position
       
  1542         // it must be adjusted to the duration of the audio clip so that playback can resume from the position where it was paused
       
  1543         if (IsLoopPlayEnabled())
       
  1544             {
       
  1545             DP1(_L("CAdvancedAudioPlayController::DoStopL() Number of times repeated = %d"), iCurrentRepeatCount);
       
  1546             iTimePositionInMicroSecs += (iAudioOutput->CalculateAudioOutputPositionL() - iSavedTimePositionInMicroSecs);
       
  1547             }
       
  1548         else
       
  1549             {
       
  1550             iTimePositionInMicroSecs += iAudioOutput->CalculateAudioOutputPositionL();
       
  1551             }
       
  1552         // clear the repeat flag
       
  1553         ClearRepeatFlag();
       
  1554 
       
  1555 	    // In order to support adaptation implementation of loop play, we cannot stop
       
  1556 	    // the output at the end of file.
       
  1557 //	    if (aError == KErrUnderflow)
       
  1558 //	        {
       
  1559 //	        TRAP_IGNORE(iAudioOutput->StopL(EFalse));
       
  1560 //	        }
       
  1561 //	    else
       
  1562 //	        {
       
  1563             TRAP_IGNORE(iAudioOutput->StopL());
       
  1564 //	        }
       
  1565 		TRAP_IGNORE(SourceSinkStopL());
       
  1566 		}
       
  1567 
       
  1568     DP0(_L("CAdvancedAudioPlayController::DoStopL state changed to stop"));
       
  1569     iState = EStopped;
       
  1570 
       
  1571     if (!iPlayingForInitPos) // internal play for seeking before user calls play
       
  1572 		{
       
  1573 		// we don't want an event if seeking past eof before play is called - we will get a playcomplete and stop
       
  1574 		// no event for a user stop which will have no error
       
  1575     	if (aError == KErrUnderflow)
       
  1576     		{
       
  1577 	    	// normal end of playback
       
  1578 			SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrNone));
       
  1579 			SendEventToClient(TMMFEvent(KStreamControlEventStateChangedStopped, KErrEof));		
       
  1580 	    	}
       
  1581     	else if (aError != KErrNone)
       
  1582 	    	{
       
  1583 	    	// processing had an error
       
  1584 	    	if (iSourceUnreadable)
       
  1585 	    	    {
       
  1586 	    	    // if source was not even readable, we never made it to user play
       
  1587 	    	    // so we don't want to send playback complete
       
  1588 	    	    }
       
  1589 	    	else
       
  1590 	    	    {
       
  1591 	    	    SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, aError));
       
  1592 	    	    SendEventToClient(TMMFEvent(KStreamControlEventStateChangedStopped, aError));
       
  1593 	    	    }
       
  1594 	    	}
       
  1595 		}
       
  1596     }
       
  1597     
       
  1598 TInt CAdvancedAudioPlayController::CleanupForStop()
       
  1599     {
       
  1600     // This is used in cases that need to initial back to a stop like state without a state change 
       
  1601     DP1(_L("CAdvancedAudioPlayController::CleanupForStop iState[%d]"), iState);
       
  1602     TInt status = KErrNone;
       
  1603     
       
  1604     iPlaySeeking = EFalse;
       
  1605     
       
  1606     if (iWait)
       
  1607         {
       
  1608         iWait->AsyncStop();
       
  1609         }
       
  1610 
       
  1611     if (iBlockSetPos)
       
  1612         {
       
  1613         if (iBlockSetPos->IsStarted())
       
  1614             {
       
  1615             iBlockSetPos->AsyncStop();
       
  1616             }
       
  1617         }
       
  1618    
       
  1619     iPlayingForDuration = EFalse;
       
  1620     iBlockDuration = EFalse;
       
  1621     iPlayingForPauseSeek = EFalse;
       
  1622     iPlayingForInitPos = EFalse;
       
  1623     iPausingForSetPos = EFalse;
       
  1624     return status;
       
  1625     }
       
  1626 
       
  1627 // -----------------------------------------------------------------------------
       
  1628 // CAdvancedAudioPlayController::ResetPositionVariables()
       
  1629 // -----------------------------------------------------------------------------
       
  1630 //
       
  1631 // These variables are always updated together, they are reset together here.
       
  1632 void CAdvancedAudioPlayController::ResetPositionVariables()
       
  1633 	{
       
  1634 	iSourceReadPosition = 0;
       
  1635 	iCurrentPosition = 0;
       
  1636 	iTimePositionInMicroSecs = 0;
       
  1637 	}
       
  1638 
       
  1639 // -----------------------------------------------------------------------------
       
  1640 // CAdvancedAudioPlayController::PositionL()
       
  1641 // -----------------------------------------------------------------------------
       
  1642 //
       
  1643 EXPORT_C TTimeIntervalMicroSeconds CAdvancedAudioPlayController::PositionL() const
       
  1644     {
       
  1645 	DP2(_L("CAdvancedAudioPlayController::PositionL, this[%x] iState[%d]"), this, iState);
       
  1646 
       
  1647 	TTimeIntervalMicroSeconds positionMicroSeconds(0);
       
  1648 
       
  1649     if (iState == EPlaying)
       
  1650     	{
       
  1651     	DP1 (_L("CAdvancedAudioPlayController::PositionL iTimePositionInMicroSecs [%d] msec"), iTimePositionInMicroSecs);
       
  1652         // adjust the position here since devsound returns the incremented postion value during loopplay
       
  1653         if (IsLoopPlayEnabled())
       
  1654             {
       
  1655             positionMicroSeconds = TTimeIntervalMicroSeconds( iAudioOutput->CalculateAudioOutputPositionL() - iSavedTimePositionInMicroSecs);
       
  1656             }
       
  1657         else
       
  1658             {
       
  1659             positionMicroSeconds = TTimeIntervalMicroSeconds(iTimePositionInMicroSecs +  iAudioOutput->CalculateAudioOutputPositionL());
       
  1660             }
       
  1661         }
       
  1662     else
       
  1663     	{
       
  1664         positionMicroSeconds = TTimeIntervalMicroSeconds(iTimePositionInMicroSecs);
       
  1665     	}
       
  1666     	
       
  1667     DP1 (_L("CAdvancedAudioPlayController::PositionL returns[%d] msec"), I64LOW(positionMicroSeconds.Int64()/1000));
       
  1668 	return positionMicroSeconds;
       
  1669 	}
       
  1670 
       
  1671 // -----------------------------------------------------------------------------
       
  1672 // CAdvancedAudioPlayController::SetPositionL
       
  1673 // -----------------------------------------------------------------------------
       
  1674 //
       
  1675 EXPORT_C void CAdvancedAudioPlayController::SetPositionL(
       
  1676     const TTimeIntervalMicroSeconds& aTimePos)
       
  1677     { // this is for user call only
       
  1678 	DP3(_L("CAdvancedAudioPlayController::SetPositionL this[%x] [%d]msec iState[%d]"), this, I64LOW(aTimePos.Int64()/1000), iState);
       
  1679     if (iSourceUnreadable)
       
  1680         {
       
  1681         DP0(_L("CAdvancedAudioPlayController::SetPositionL KErrCorrupt"));
       
  1682         User::Leave(KErrCorrupt);
       
  1683         }
       
  1684 
       
  1685     // if play window is set then validate the position with the play window boundaries
       
  1686     // play window boundaries must be checked when seeking during playback in a playwindow
       
  1687     TTimeIntervalMicroSeconds position = aTimePos;
       
  1688     // if play window is set then the playwindowendposition is > 0
       
  1689     if (iPlayWindowEndPosition > 0)
       
  1690         {
       
  1691         if (aTimePos < iPlayWindowStartPosition)
       
  1692             {
       
  1693             position = iPlayWindowStartPosition;
       
  1694             }
       
  1695         else if (aTimePos > iPlayWindowEndPosition)
       
  1696             {
       
  1697             position = iPlayWindowEndPosition;
       
  1698             }
       
  1699         }
       
  1700 
       
  1701 	switch (iState)
       
  1702 		{
       
  1703 		case EStopped:
       
  1704 		case EInitializing:
       
  1705             if (position != 0)
       
  1706     	   		{ // if we are priming, we will already be ready to play from 0.
       
  1707 				DP2(_L("CAdvancedAudioPlayController::SetPositionL, saving pos iReadHeader[%d] iState[%d]"),iReadHeader,iState);
       
  1708                 iInitPosition = position;
       
  1709        			}
       
  1710 			DP0(_L("CAdvancedAudioPlayController::SetPositionL, can ignore"));
       
  1711 			break;
       
  1712 		case EInitialized:
       
  1713 		case EPaused:
       
  1714 		    iSavedSetPosition = position;
       
  1715             DoSetPositionL(position);
       
  1716    			if (iPlaySeeking)
       
  1717    				{
       
  1718 		        DP0(_L("CAdvancedAudioController::SetPositionL() blocking"));
       
  1719 		        iBlockSetPos = new (ELeave) CActiveSchedulerWait();
       
  1720 		        iBlockSetPos->Start();
       
  1721     		    DP0(_L("CAdvancedAudioController::SetPositionL() continuing"));
       
  1722 	    	    delete iBlockSetPos;
       
  1723    		    	iBlockSetPos = NULL;
       
  1724    				}
       
  1725 			break;
       
  1726 		case EAutoPaused:
       
  1727 		case EPlaying:
       
  1728             DP0(_L("CAdvancedAudioPlayController::SetPositionL, PauseForSetPosL so we can set position"));
       
  1729 			PauseForSetPosL(); // will return to play state when position reached
       
  1730 		    iSavedSetPosition = position;
       
  1731 			DP0(_L("CAdvancedAudioPlayController::SetPositionL, After PauseForSetPosL, now set the desired position"));
       
  1732             DoSetPositionL(position);
       
  1733             if (iPlaySeeking)
       
  1734                 {
       
  1735                 DP0(_L("CAdvancedAudioController::SetPositionL() blocking"));
       
  1736                 iBlockSetPos = new (ELeave) CActiveSchedulerWait();
       
  1737                 iBlockSetPos->Start();
       
  1738                 DP0(_L("CAdvancedAudioController::SetPositionL() continuing"));
       
  1739                 delete iBlockSetPos;
       
  1740                 iBlockSetPos = NULL;
       
  1741                 }
       
  1742             else
       
  1743                 {
       
  1744                 DP0(_L("CAdvancedAudioPlayController::SetPositionL Calling SeekPositionReached "));
       
  1745                 // comes here if seek position found in source, or starting another loop during loop play
       
  1746                 // during loop play we seek back to the beginning of the clip or play window start position.
       
  1747                 SeekPositionReached(KMaxTUint);
       
  1748                 }
       
  1749 	        break;
       
  1750 		}
       
  1751 	}
       
  1752 
       
  1753 // -----------------------------------------------------------------------------
       
  1754 // CAdvancedAudioPlayController::SetPrioritySettings
       
  1755 // -----------------------------------------------------------------------------
       
  1756 //
       
  1757 EXPORT_C void CAdvancedAudioPlayController::SetPrioritySettings(
       
  1758     const TMMFPrioritySettings& aPrioritySettings)
       
  1759     {
       
  1760 	DP0(_L("CAdvancedAudioPlayController::SetPrioritySettings"));
       
  1761 
       
  1762     CAdvancedAudioController::SetPrioritySettings(aPrioritySettings);
       
  1763 
       
  1764     if(iDataSink)
       
  1765         {
       
  1766         TRAPD(err, iAudioOutput->SetPrioritySettingsL(aPrioritySettings));
       
  1767 		err = err;
       
  1768         }
       
  1769     }
       
  1770     
       
  1771 // -----------------------------------------------------------------------------
       
  1772 // CAdvancedAudioPlayController::SendEventToClient
       
  1773 // -----------------------------------------------------------------------------
       
  1774 //
       
  1775 EXPORT_C TInt CAdvancedAudioPlayController::SendEventToClient(const TMMFEvent& aEvent)
       
  1776     {
       
  1777     DP4(_L("CAdvancedAudioPlayController::SendEventToClient, this[%x] iEventsEnabled[%d], iEventType[%d], ErrorCode[%d]"), this, iEventsEnabled, aEvent.iEventType, aEvent.iErrorCode);
       
  1778 
       
  1779     // The following logic is to take care of only forward the appropiate event depends on "iEventsEanbled" flag
       
  1780     // KMMFEventCategoryPlaybackComplete event is to support the Existing Symbian MMF API behavior
       
  1781     // while KStreamControlEventStateChangedXXX for Streaming/PDL events, and ONLY ONE of these events should be forwarded to the client
       
  1782     // Current implementation is instead of deciding what event when a SendEventToClient issued, both events would be sent, and the decision
       
  1783     // on which one to be forwarded is being implemented here
       
  1784     // *NOTE*:  KStreamControlEventStateChangedStopped does NOT equal to KMMFEventCategoryPlaybackComplete,
       
  1785     //          while both would happends during error situation, KStreamControlEventStateChangedStopped also happens when StopL is called
       
  1786     //          but KMMFEventCategoryPlaybackComplete would not
       
  1787     if( (aEvent.iErrorCode == KErrSourceAdapter) || ( aEvent.iErrorCode == KErrCorrupt ) )
       
  1788     	{//Stop the controller and send error since error occured in source adapter 
       
  1789         iSourceUnreadable = ETrue;
       
  1790     	DoStopL(KErrDied);
       
  1791         }
       
  1792     else
       
  1793     	{
       
  1794     	if (iEventsEnabled)
       
  1795     	    { // request for new events
       
  1796     	    if ((aEvent.iEventType == KStreamControlEventStateChangedStopped) ||
       
  1797    	            (aEvent.iEventType == KStreamControlEventStateChangedPrimed)  ||
       
  1798    	            (aEvent.iEventType == KStreamControlEventStateChangedPlaying) ||
       
  1799    	            (aEvent.iEventType == KStreamControlEventStateChangedPaused)  ||
       
  1800    	            (aEvent.iEventType == KStreamControlEventStateChangedAutoPaused))
       
  1801     	        {
       
  1802     	        return CAdvancedAudioController::SendEventToClient(aEvent);
       
  1803     	        }
       
  1804     	    else
       
  1805     	        {
       
  1806     	        // do not send any other events for advanced clients.	
       
  1807     	        }
       
  1808     	    }
       
  1809     	else
       
  1810     	    {
       
  1811     	    if ((aEvent.iEventType == KStreamControlEventStateChangedStopped) ||
       
  1812     	        (aEvent.iEventType == KStreamControlEventStateChangedPrimed)  ||
       
  1813     	        (aEvent.iEventType == KStreamControlEventStateChangedPlaying) ||
       
  1814     	        (aEvent.iEventType == KStreamControlEventStateChangedPaused)  ||
       
  1815     	        (aEvent.iEventType == KStreamControlEventStateChangedAutoPaused))
       
  1816     	        {
       
  1817     	        // ignore event and do nothing except convert autopause to old event
       
  1818     	        }
       
  1819     	    else
       
  1820     	        {
       
  1821     	        return CAdvancedAudioController::SendEventToClient(aEvent);
       
  1822     	        }            
       
  1823     	    }
       
  1824     	}   
       
  1825     return KErrNone;
       
  1826     }
       
  1827 
       
  1828 // -----------------------------------------------------------------------------
       
  1829 // CAdvancedAudioPlayController::BufferFilledL
       
  1830 // Called after the data buffer is filled.
       
  1831 // -----------------------------------------------------------------------------
       
  1832 //
       
  1833 EXPORT_C void CAdvancedAudioPlayController::BufferFilledL(CMMFBuffer* aBuffer)
       
  1834     {
       
  1835 	aBuffer->SetPosition(0);
       
  1836     CMMFDataBuffer* buffer = static_cast<CMMFDataBuffer*>(aBuffer);
       
  1837 
       
  1838     DP6(_L("CAdvancedAudioPlayController::BufferFilledL[%x], readPos[%d], Length[%d], iState[%d], LB[%d], d0[%x]"),
       
  1839         buffer->Data().Ptr(), iSourceReadPosition, buffer->Data().Length(), iState, aBuffer->LastBuffer(),
       
  1840         buffer->Data().Ptr()[0]);
       
  1841     
       
  1842 	if ((buffer->Data().Length() > 0) || buffer->LastBuffer())
       
  1843 	    {
       
  1844 	    aBuffer->SetStatus(EFull);
       
  1845 			
       
  1846 		// iSourceReadPosition is used to mark the buffer with the source position
       
  1847 		// This is stored in aBuffer->Frame(). aBuffer->Frame() will indicate
       
  1848 		// the source position for the starting byte position for that buffer
       
  1849 		aBuffer->SetFrameNumber(iSourceReadPosition);
       
  1850 		iSourceReadPosition += buffer->Data().Length();
       
  1851 
       
  1852         DP1(_L("CAdvancedAudioPlayController::BufferFilledL next readPos[%d]"),	iSourceReadPosition);
       
  1853 	    }
       
  1854     else
       
  1855         {
       
  1856 		DP0(_L("CAdvancedAudioPlayController::BufferFilledL, unexpected 0 length buffer"));
       
  1857 		User::Leave(KErrAbort);
       
  1858         }
       
  1859 
       
  1860     if (iState != EStopped)
       
  1861         {
       
  1862         DoBufferFilledL(aBuffer);
       
  1863         }
       
  1864 
       
  1865 	TBool doState = ETrue;    
       
  1866 	while (doState)
       
  1867 		{
       
  1868 		DP5(_L("CAdvancedAudioPlayController::BufferFilledL, state check state[%d] reqstate[%d] pfps[%d] pfd[%d] pfip[%d]"),
       
  1869 				iState, iRequestState, iPlayingForPauseSeek,iPlayingForDuration,iPlayingForInitPos);
       
  1870 		doState = EFalse;
       
  1871 		switch (iState)
       
  1872 			{
       
  1873 			case EStopped:
       
  1874                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EStopped"));
       
  1875 				break;
       
  1876 			case EInitializing:
       
  1877                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EInitializing"));
       
  1878 				if (!iReadHeader)
       
  1879 					{
       
  1880 					// do not transition to initialized if there was a problem
       
  1881 				    if (iSourceUnreadable)
       
  1882 				        {
       
  1883 				        return;
       
  1884 				        }
       
  1885 					iState = EInitialized;
       
  1886 					// when playwindow is active for a non-seekable source during loop play
       
  1887 					// we must seek to the playwindow start position and then start the playback
       
  1888 					if (iPlayWindowStartPosition > 0) // do we need additional checks as loop play / non-seekable source ??
       
  1889 					    iInitPosition = iPlayWindowStartPosition;
       
  1890     				GoToInitPositionL(); // see if we need to seek to somewhere
       
  1891 					doState = ETrue;
       
  1892 					}
       
  1893 				break;
       
  1894 			case EInitialized:
       
  1895                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EInitialized"));
       
  1896                 if ((iRequestState == EInitialized) && AllBuffersFilled() && iEnablePrimedStateChangedEvent)
       
  1897                     { // we have read the header, user has called prime but needed to wait for priming, all the input buffers are filled
       
  1898                     // the controller itself may need to prime to get duration, but we just want to send the state change in response to user prime
       
  1899                     iEnablePrimedStateChangedEvent = EFalse;
       
  1900                     DP0(_L("CAdvancedAudioPlayController::BufferFilledL state changed primed"));
       
  1901                     SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPrimed, KErrNone)); // both source and sink are ready.
       
  1902                     }
       
  1903 				if ((iRequestState == EPlaying)	|| iPlayingForDuration || iPlayingForPauseSeek || iPlayingForInitPos)
       
  1904 					{
       
  1905 		            if (iAudioOutput->IsDSStopped())
       
  1906                         {
       
  1907                         DP0(_L("CAdvancedAudioPlayController::BufferFilledL calling DoPlayL Devsound is stopped iState=EInitialized"));
       
  1908                         DoPlayL();
       
  1909                         }
       
  1910                     else
       
  1911                         {
       
  1912                         // This is needed for non-seekable sources as DoRepeat() calls DoInitialize in this case
       
  1913                         // this resets the source to read from 0 and sets the iState to EInitializing.
       
  1914                         // BufferFilled will not read the header again, change state to EInitialized and seek to the iInitPosition.
       
  1915                         // The next BufferFilled will come here, where we will continue playback from byte position 0
       
  1916                         // that is now in the buffers.
       
  1917                         DP0(_L("CAdvancedAudioPlayController::BufferFilledL Resuming the playback iState=EInitialized"));
       
  1918                         // we need to be able to seek fwd to playwindow start pos
       
  1919                         if (IsLoopPlayEnabled())
       
  1920                             {
       
  1921                             DoResume(iCurrentPosition);
       
  1922                             }
       
  1923                         else
       
  1924                             {
       
  1925                             DoPlayL();
       
  1926                             }
       
  1927 
       
  1928                         }
       
  1929 					}
       
  1930 				break;
       
  1931 			case EPlaying:
       
  1932                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EPlaying"));
       
  1933 				break;				
       
  1934 			case EPaused:
       
  1935                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EPaused"));
       
  1936                 // iPlayingForPauseSeek would be set if we are in pause mode and we need to seek.
       
  1937                 // the controller will not go to play state until all buffers are filled.
       
  1938                 // so we need to call DoPlay until all buffers are filled and transition to play state.
       
  1939                 // if PauseForSetPos, we will resume play in seekpositionreached.
       
  1940                 // if (((iRequestState == EPlaying) || iPlayingForPauseSeek) && (!iPausingForSetPos) ) Suk
       
  1941                 if ((iRequestState == EPlaying) || iPlayingForPauseSeek)
       
  1942 					{
       
  1943 		            if (iAudioOutput->IsDSStopped())
       
  1944                         { // during loop play the output is not stopped unless we did a seek - seek stops the output and we need to call DoPlay
       
  1945                         DP0(_L("CAdvancedAudioPlayController::BufferFilledL Calling DoPlay Devsound is stopped iState=EPaused"));
       
  1946                         DoPlayL();
       
  1947 					    }
       
  1948 					else
       
  1949 					    {
       
  1950                         DP1(_L("CAdvancedAudioPlayController::BufferFilledL Calling DoResume iState=EPaused iCurrentPosition[%d]"), iCurrentPosition);
       
  1951                         if (IsLoopPlayEnabled())
       
  1952                             {
       
  1953                             DoResume(iCurrentPosition);
       
  1954                             }
       
  1955                         else
       
  1956                             {
       
  1957                             DP0(_L("CAdvancedAudioPlayController::BufferFilledL Calling DoPlay iState=EPaused"));
       
  1958                             DoPlayL();
       
  1959                             }
       
  1960 					    }
       
  1961                     }
       
  1962 				break;
       
  1963 			case EAutoPaused:
       
  1964                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EAutoPaused"));
       
  1965                 DoResume();
       
  1966 				break;
       
  1967     	    default:
       
  1968                 DP0(_L("CAdvancedAudioPlayController::BufferFilledL EBadState"));
       
  1969         	    Panic(EBadState);
       
  1970             	break;
       
  1971 	 		}
       
  1972 		}
       
  1973     }
       
  1974 
       
  1975 void CAdvancedAudioPlayController::DoResume(TInt aResumePosition) // defaults to -1
       
  1976 	{
       
  1977     DP3(_L("CAdvancedAudioPlayController::DoResume iState[%d] iRequestState[%d] aResumePosition[%d]"), iState, iRequestState, aResumePosition);
       
  1978     TInt bufferIndex = -1;
       
  1979     if (aResumePosition >= 0)
       
  1980         {
       
  1981         iResumePosition = aResumePosition;
       
  1982         DP2(_L("CAdvancedAudioPlayController::DoResume saving resume position [%d] iState[%d]"), iResumePosition, iState);
       
  1983         }
       
  1984 
       
  1985 		if (iCurrentPosition == KMaxTUint)
       
  1986 			{
       
  1987             DP0(_L("CAdvancedAudioPlayController::DoResume Resetting iCurrentPosition to zero"));
       
  1988 			iCurrentPosition = 0;
       
  1989 			}
       
  1990 
       
  1991 	if (AllBuffersFilled()) // state entry condition
       
  1992 		{
       
  1993         if (iResumePosition >= 0)
       
  1994             {
       
  1995             bufferIndex = FindBufferFromPos(iResumePosition);
       
  1996             DP1(_L("CAdvancedAudioPlayController::DoResume bufferIndex [%d]"), bufferIndex);
       
  1997             iResumePosition = -1;
       
  1998             DP0(_L("CAdvancedAudioPlayController::DoResume Resetting the ResumePosition"));
       
  1999             // if there was seek past end of file, the buffers may not have any data
       
  2000             // they may all be empty last buffers
       
  2001             if ((bufferIndex < 0) && (AllBuffersEmpty()))
       
  2002                 { // position in buffer buffer not found
       
  2003                 DP0(_L("CAdvancedAudioPlayController::DoResume Position in the buffer not found "));
       
  2004                 DoStopL(KErrNone);
       
  2005                 return;
       
  2006                 }
       
  2007             if (bufferIndex < 0)
       
  2008                 {
       
  2009                 DP0(_L("CAdvancedAudioPlayController::DoResume bufferindex < 0"));
       
  2010                 DoStopL(KErrGeneral);
       
  2011                 return;
       
  2012                 }
       
  2013             }
       
  2014 
       
  2015         TInt errExIntent = KErrNone;
       
  2016         if (!iDisableAutoIntent && (iRequestState == EPlaying))
       
  2017             {
       
  2018             if (iIntentStopped)
       
  2019                 {
       
  2020                 errExIntent = iDataSourceAdapter->EvaluateIntent(ContentAccess::EPlay);
       
  2021                 if (errExIntent == KErrNone)
       
  2022                     {
       
  2023                     errExIntent = iDataSourceAdapter->ExecuteIntent(ContentAccess::EPlay);
       
  2024                     DP2(_L("CAdvancedAudioPlayController::DoResume() iIntentStopped[%d] errExIntent[%d]"), iIntentStopped, errExIntent );
       
  2025                     if (errExIntent == KErrNone)
       
  2026                         iIntentStopped = EFalse;
       
  2027                     }
       
  2028                 else // if ((errExIntent == KErrKErrNoRights) || any other error)
       
  2029                     {
       
  2030                     DoStopL(errExIntent);
       
  2031                     return;
       
  2032                     }
       
  2033                 }
       
  2034             else
       
  2035                 {
       
  2036                 errExIntent = iDataSourceAdapter->EvaluateIntent((iState == EPaused) ? ContentAccess::EContinue : ContentAccess::EPlay);
       
  2037                 if (errExIntent == KErrNone)
       
  2038                     {
       
  2039                     errExIntent = iDataSourceAdapter->ExecuteIntent((iState == EPaused) ? ContentAccess::EContinue : ContentAccess::EPlay);
       
  2040                     DP2(_L("CAdvancedAudioPlayController::DoResume() iIntentStopped[%d] errExIntent[%d]"), iIntentStopped, errExIntent );
       
  2041                     }
       
  2042                 else // if ((errExIntent == KErrKErrNoRights) || any other error)
       
  2043                     {
       
  2044                     DoStopL(errExIntent);
       
  2045                     return;
       
  2046                     }
       
  2047                 }
       
  2048             }
       
  2049         if ((errExIntent != KErrNone) && (errExIntent != KErrNotSupported))
       
  2050             {
       
  2051             DP1(_L("CAdvancedAudioPlayController::DoResume() errExIntent[%d]"), errExIntent);
       
  2052             return;
       
  2053             }
       
  2054 
       
  2055         DP1(_L("CAdvancedAudioPlayController::DoResume iAudioOutput->Resume with bufferIndex [%d]"), bufferIndex);
       
  2056 		iState = EPlaying;
       
  2057 		// iRequestState should not be changed since it represents user request.
       
  2058         iAudioOutput->Resume(bufferIndex);
       
  2059 
       
  2060         if ((!iRepeatForever) && (iCurrentRepeatCount == iRepeatCount))
       
  2061             { // this is the last play of the repeats so tell the AudioOutput to set the lastbuffer to True
       
  2062             DP1(_L("CAdvancedAudioPlayController::DoResume iCurrentRepeatCount[%d]"), iCurrentRepeatCount);
       
  2063             iAudioOutput->UnSetLastBuffer(EFalse);
       
  2064             }
       
  2065         SendEventToClient(TMMFEvent(KStreamControlEventStateChangedPlaying, KErrNone));
       
  2066 		}
       
  2067 	}
       
  2068 
       
  2069 
       
  2070 TBool CAdvancedAudioPlayController::AllBuffersFilled()
       
  2071 	{
       
  2072     DP0(_L("CAdvancedAudioPlayController::AllBuffersFilled"));
       
  2073 	TBool allFilled = ETrue;
       
  2074 	for (TInt i = 0; i < iSharedBufferMaxNum; i++)
       
  2075 		{
       
  2076 		if (iSharedBuffers[i]->LastBuffer() && iSharedBuffers[i]->Status() == EFull)
       
  2077 		    { // if one buffer is filled and marked last buffer
       
  2078 			allFilled = ETrue;
       
  2079 			break;
       
  2080 			}
       
  2081 	    else if (iSharedBuffers[i]->Status() == EBeingFilled)
       
  2082 	    	{
       
  2083 			allFilled = EFalse;
       
  2084 	    	}
       
  2085 		}
       
  2086     DP1(_L("CAdvancedAudioPlayController::AllBuffersFilled [%d]"),allFilled);
       
  2087 	return allFilled;
       
  2088 	}
       
  2089 
       
  2090 TBool CAdvancedAudioPlayController::AllBuffersEmpty()
       
  2091 	{
       
  2092     DP0(_L("CAdvancedAudioPlayController::AllBuffersEmpty"));
       
  2093 	TBool allEmpty = ETrue;
       
  2094 	for (TInt i = 0; i < iSharedBufferMaxNum; i++)
       
  2095 		{
       
  2096         DP3(_L("CAdvancedAudioPlayController::AllBuffersEmpty indx[%d] len[%d] stat[%d]"), i, iSharedBuffers[i]->BufferSize(), iSharedBuffers[i]->Status());
       
  2097 		if ((iSharedBuffers[i]->BufferSize() != 0) && 
       
  2098 		    (iSharedBuffers[i]->Status() == EFull))
       
  2099 		    {
       
  2100 			allEmpty = EFalse;
       
  2101 			break;
       
  2102 		    }
       
  2103 		}
       
  2104     DP1(_L("CAdvancedAudioPlayController::AllBuffersEmpty [%d]"), allEmpty);
       
  2105 	return allEmpty;
       
  2106 	}
       
  2107 
       
  2108 
       
  2109 void CAdvancedAudioPlayController::DoBufferFilledL(CMMFBuffer* aBuffer)
       
  2110 	{
       
  2111     DP0(_L("CAdvancedAudioPlayController::DoBufferFilledL"));
       
  2112 
       
  2113     CMMFDataBuffer* buffer = static_cast<CMMFDataBuffer*>(aBuffer);
       
  2114 	if (iReadHeader)
       
  2115 	    {
       
  2116 	    TRAPD(err, DoReadHeaderL(buffer));
       
  2117 	    DP2(_L("CAdvancedAudioPlayController::DoBufferFilledL header is read iHeaderOffset[%d] iSyncOffset[%d]"), iHeaderOffset, iSyncOffset);
       
  2118 	    DP1(_L("CAdvancedAudioPlayController::DoBufferFilledL DoReadHeaderL err[%d]"), err);
       
  2119 			
       
  2120     	if (((err == KErrNotReady) || (err == KErrNotFound) || (err == KErrCompletion && iSourceIsPosSeekable)) && !aBuffer->LastBuffer())
       
  2121 			{
       
  2122             // this shared buffer does not contain any part of the first frame
       
  2123 		    DP0(_L("CAdvancedAudioPlayController::DoBufferFilledL iInitPosition = 0 to seek back to start when done"));
       
  2124 			iInitPosition = 0; // if we are going to throw away these buffers, we need to indicate we need to seek back to the start
       
  2125 			RefillBuffer(aBuffer);
       
  2126 			}
       
  2127 		else
       
  2128 			{
       
  2129 			if ( err == KErrCompletion )
       
  2130 				{
       
  2131 				if(((iSharedBufferCnt+1)  < iSharedBufferMaxNum) && !aBuffer->LastBuffer())
       
  2132 					{
       
  2133 					iSharedBufferCnt++;	
       
  2134 					return;	
       
  2135 					}
       
  2136 				else
       
  2137 					{
       
  2138 					err = KErrNone;	
       
  2139 					}
       
  2140 				}
       
  2141 				
       
  2142 			iReadHeader = EFalse;
       
  2143 			if (err != KErrNone)		    
       
  2144 				{
       
  2145 				if (((err == KErrNotReady) || (err == KErrNotFound)) && (aBuffer->LastBuffer()))
       
  2146 					{
       
  2147 					// we went through the whole file without finding the header
       
  2148 					// so the source is corrupted
       
  2149 				    DP0(_L("CAdvancedAudioPlayController::DoBufferFilledL KErrCorrupt"));
       
  2150 					err = KErrCorrupt;
       
  2151 					iSourceUnreadable = ETrue;
       
  2152 					}
       
  2153 				TRAP_IGNORE(DoStopL(err));
       
  2154 				}
       
  2155 			else
       
  2156 				{
       
  2157 		        if (iAudioUtility)
       
  2158 		            { // 3gp won't have a utility until it reads the header info
       
  2159         		    TInt sourceSize = iDataSourceAdapter->SourceSize();
       
  2160         		    if (sourceSize < 0)
       
  2161         		        {
       
  2162         		        sourceSize = 0;
       
  2163         		        }
       
  2164 		           	TRAP_IGNORE(iAudioUtility->SetClipSizeL(sourceSize));
       
  2165         		    }
       
  2166 
       
  2167         	    iCurrentPosition = iHeaderOffset+iSyncOffset;
       
  2168                 DP3(_L("CAdvancedAudioPlayController::DoBufferFilledL header read curpos[%d] hdroff[%d] syncoff[%d]"),
       
  2169                         iCurrentPosition, iHeaderOffset, iSyncOffset);
       
  2170         	    iTimePositionInMicroSecs = 0;
       
  2171         	    if (iAudioUtility)
       
  2172         	        {
       
  2173 					iAudioUtility->SetSourceReference(0,0);
       
  2174         	        }
       
  2175 
       
  2176 				UpdateDuration();
       
  2177 				UpdateBitRate();
       
  2178 				// we need to unblock any blocked duration call and also disable it from blocking
       
  2179 				// since we now have duration and bitrate.
       
  2180 				iBlockDuration = EFalse;
       
  2181 				if (iWait)
       
  2182 				    {
       
  2183     				iWait->AsyncStop(); // unblock Duration() now that duration is calculated
       
  2184 					}
       
  2185 				
       
  2186 				// Sink may not be provided yet. Client might add source first.
       
  2187 				// Or a client trying to get duration may not have provided a sink.
       
  2188 				// Without a sink, we'll just return here, but know that we have read enough
       
  2189 				// source data to configure the sink once it is added.
       
  2190 				// But if the sink is available here, we'll initialize below.
       
  2191 				iSinkInitDataReady = ETrue; 
       
  2192 				// Primed state change event would be sent when both source and sink are ready.
       
  2193 				if (!iAudioOutput)
       
  2194 					{
       
  2195 //					iBlockDuration = EFalse;
       
  2196 //					if (iWait)
       
  2197 //					    {
       
  2198 // 	    				iWait->AsyncStop(); // unblock Duration() now that duration is calculated
       
  2199 //						}
       
  2200 					return;
       
  2201 					}
       
  2202 				DoInitializeSinkL(); // the decoder will be created here
       
  2203 				}
       
  2204 			}    		    
       
  2205 		}
       
  2206     }
       
  2207 
       
  2208 EXPORT_C void CAdvancedAudioPlayController::DoInitializeSinkL()
       
  2209 	{
       
  2210 	DP0(_L("CAdvancedAudioPlayController::DoInitializeSinkL"));
       
  2211 	iSinkInitDataReady = EFalse;
       
  2212 	
       
  2213 	//both source and sink have been added
       
  2214      if(iAudioOutput && iDataSourceAdapter)     
       
  2215          {
       
  2216          iAudioOutput->SetDataSourceAdapter(iDataSourceAdapter);
       
  2217          }
       
  2218 	
       
  2219 	if (!iDecoderExists)
       
  2220 	    {
       
  2221 	    // move this common code to here from doadddatasink's	
       
  2222 	    CAdvancedAudioDecoder* decoder = BuildDecoderL();
       
  2223 	    iDecoderExists = ETrue;
       
  2224 	    // AudioOutput takes ownership of decoder object
       
  2225 	    iAudioOutput->SetDecoder(decoder);
       
  2226 	    iAudioUtility->SetDecoder(*decoder);
       
  2227 	    iAudioUtility->SetObserver(*this);
       
  2228 	    decoder->SetDecoderUtilityObserver(*iAudioUtility);
       
  2229 
       
  2230 	    // Leave if HWCodec and Conversion tried
       
  2231 	    if(decoder->IsHwAccelerated() && iDataSink->DataSinkType() == KUidMmfFileSink)
       
  2232 	        {
       
  2233 	        User::Leave(KErrNotSupported);
       
  2234 	        }
       
  2235 	    }
       
  2236 	
       
  2237 	
       
  2238 	
       
  2239     // Read the default codec configuration parameters from resource file
       
  2240 	RArray<TInt>& codecConfigData = const_cast<RArray<TInt>&>(iAudioResource->CodecConfigParametersL());
       
  2241 	// Override default values with values found from header, if available
       
  2242 	GetCodecConfigData(codecConfigData);
       
  2243 	iAudioOutput->ConfigureL(iSampleRate, iSinkNumChannels, iDataType, codecConfigData);
       
  2244     DP0(_L("CAdvancedAudioPlayController::DoInitializeSinkL, output configured"));
       
  2245 	iAudioOutput->PrimeL();
       
  2246     DP0(_L("CAdvancedAudioPlayController::DoInitializeSinkL, output primed"));
       
  2247 			    
       
  2248 	// we would use this code when we have a NULL sink
       
  2249 /*	if (iDuration > 0)
       
  2250 		{
       
  2251 		DP0(_L("CAdvancedAudioPlayController::BufferFilledL, unblocking duration"));
       
  2252 		iBlockDuration = EFalse;
       
  2253 		}
       
  2254 	if (iWait)
       
  2255 	    {
       
  2256 	    if (iDuration > 0)
       
  2257 	        {
       
  2258             DP0(_L("CAdvancedAudioPlayController::DoBufferFilledL() unblocking"));
       
  2259 			iWait->AsyncStop(); // unblock DoAddDataSource now that duration is calculated
       
  2260 	        }
       
  2261 	    else
       
  2262 	        {
       
  2263 	        PlayForDurationL(); // this should only be used if we are given a NULL sink
       
  2264 	        }                  // because policy will get involved with an audio output sink
       
  2265 	    }                      // We can skip using this even for NULL sink if we just continue to
       
  2266 */
       
  2267 	}                          // stay in read header mode and calulate bitrate on more buffers
       
  2268     
       
  2269 void CAdvancedAudioPlayController::PlayForDurationL()
       
  2270     {
       
  2271     DP0(_L("CAdvancedAudioPlayController::PlayForDurationL()"));
       
  2272     iPlayingForDuration = ETrue;
       
  2273     DoSetPositionL(1000000); // 1 sec
       
  2274     DoPlayL();
       
  2275     }
       
  2276     
       
  2277 void CAdvancedAudioPlayController::PlayForInitPositionL()
       
  2278     {
       
  2279     DP0(_L("CAdvancedAudioPlayController::PlayForInitPositionL()"));
       
  2280     iPlayingForInitPos = ETrue;
       
  2281     DoPlayL();
       
  2282     }
       
  2283 
       
  2284 void CAdvancedAudioPlayController::PlayForPauseSeekL()
       
  2285 	{
       
  2286     DP1(_L("CAdvancedAudioPlayController::PlayForPauseSeekL() pfsp[%d]"), iPausingForSetPos);
       
  2287     if (!iPausingForSetPos)
       
  2288     	{ // used to return the state to pause
       
  2289 	    iPlayingForPauseSeek = ETrue;
       
  2290     	}
       
  2291     DoPlayL();
       
  2292 	}
       
  2293 
       
  2294 void CAdvancedAudioPlayController::PauseForSetPosL()
       
  2295 	{
       
  2296     DP0(_L("CAdvancedAudioPlayController::PauseForSetPosL()"));
       
  2297     iPausingForSetPos = ETrue; // so that pause won't set position too.
       
  2298     DoPauseL(); // stops the output for reposition - it also repositions at pause point using dosetposition
       
  2299 	}
       
  2300 
       
  2301 TInt CAdvancedAudioPlayController::DoSetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
       
  2302     {
       
  2303     DP2(_L("CAdvancedAudioPlayController::SetRepeats RepeatCount [%d] TrailingSilencePeriod [%d]"), aRepeatNumberOfTimes, I64LOW(aTrailingSilence.Int64()/1000));
       
  2304     if ((aRepeatNumberOfTimes != KMdaRepeatForever) && (aRepeatNumberOfTimes <= 0))
       
  2305         {
       
  2306         return KErrArgument;
       
  2307         }
       
  2308     if (aTrailingSilence < 0)
       
  2309         {
       
  2310         return KErrArgument;
       
  2311         }
       
  2312 
       
  2313     if (aRepeatNumberOfTimes == KMdaRepeatForever) // -2
       
  2314         {
       
  2315         iRepeatForever = ETrue;
       
  2316         }
       
  2317     else
       
  2318         {
       
  2319         iRepeatForever = EFalse;
       
  2320         }
       
  2321     iRepeatCount = aRepeatNumberOfTimes;
       
  2322     iLoopPlayEnabled = ETrue;
       
  2323     if (aTrailingSilence.Int64() > KMaxTInt)
       
  2324         {
       
  2325         iTrailingSilenceMs = TTimeIntervalMicroSeconds32(KMaxTInt);
       
  2326         }
       
  2327     else
       
  2328         {
       
  2329         iTrailingSilenceMs = TTimeIntervalMicroSeconds32(aTrailingSilence.Int64());
       
  2330         }
       
  2331     if (iAudioOutput)
       
  2332         {
       
  2333         iAudioOutput->IsLoopPlayEnabled(iLoopPlayEnabled);
       
  2334         iAudioOutput->UnSetLastBuffer(ETrue);
       
  2335         }
       
  2336     if (iTrailingSilenceTimer)
       
  2337         {
       
  2338         delete iTrailingSilenceTimer;
       
  2339         iTrailingSilenceTimer = NULL;
       
  2340         }
       
  2341     iTrailingSilenceTimer = CTrailingSilenceTimer::NewL(*this);
       
  2342     // if MapcSetRepeats is called twice or more from the client side,
       
  2343     // then the loop play re-starts and the latest repeat count is considered for
       
  2344     // loop play operation. Reset the counter and the samplesplayed value
       
  2345     iCurrentRepeatCount = 0;
       
  2346     iSavedTimePositionInMicroSecs = 0;
       
  2347     return KErrNone;
       
  2348     }
       
  2349 
       
  2350 void CAdvancedAudioPlayController::ClearRepeatFlag()
       
  2351     {
       
  2352     DP0(_L("CAdvancedAudioPlayController::ClearRepeatFlag"));
       
  2353     iLoopPlayEnabled = EFalse;
       
  2354     if (iAudioOutput)
       
  2355         {
       
  2356         iAudioOutput->IsLoopPlayEnabled(iLoopPlayEnabled);
       
  2357         iAudioOutput->UnSetLastBuffer(EFalse);
       
  2358         }
       
  2359     }
       
  2360 
       
  2361 EXPORT_C void CAdvancedAudioPlayController::LastBufferSent()
       
  2362     { // this is the callback we will get during loop play, instead of playcomplete/dostop
       
  2363     DP2(_L("CAdvancedAudioPlayController::LastBufferSent Begin iRequestedState [%d] iState [%d]"), iRequestState, iState);
       
  2364     if (!iDisableAutoIntent)
       
  2365         {
       
  2366         TInt errExIntent = iDataSourceAdapter->ExecuteIntent(ContentAccess::EStop);
       
  2367         DP1(_L("CAdvancedAudioPlayController::LastBufferSent Calling ExecuteIntent Stop on DataSource [%d]"), errExIntent);
       
  2368         if (errExIntent == KErrNone)
       
  2369             {
       
  2370             iIntentStopped = ETrue;
       
  2371             }
       
  2372         }
       
  2373     if ((iRequestState == EPlaying) && (iState == EPlaying) && (IsLoopPlayEnabled())) // evaluate use of iState
       
  2374         {
       
  2375         // start timer and let it's RunL call repeat
       
  2376         if (iTrailingSilenceTimer)
       
  2377             {
       
  2378             DP1(_L("CAdvancedAudioPlayController::LastBufferSent Waiting for the iTrailingSilenceTimer for [%d] ms"), I64LOW(iTrailingSilenceMs.Int()/1000));
       
  2379             iTrailingSilenceTimer->After(iTrailingSilenceMs);
       
  2380             }
       
  2381         // save the current position, this will be used to calculate the position in loop play when
       
  2382         // client calls for PositionL() or Pause() operations
       
  2383         // TODO:  need to check this position when loop play is going on in a play window
       
  2384         // iSavedTimePositionInMicroSecs = iAudioOutput->CalculateAudioOutputPositionL();
       
  2385 
       
  2386         /* if ((!iRepeatForever) && (iCurrentRepeatCount < iRepeatCount))
       
  2387             {
       
  2388             iCurrentRepeatCount++;
       
  2389             }
       
  2390         DP1(_L("CAdvancedAudioPlayController::LastBufferSent() Number of times played till now = %d"), iCurrentRepeatCount);
       
  2391         */
       
  2392         }
       
  2393     //else if ((iState == EPaused) && 
       
  2394     /*
       
  2395      * This is needed for TruePause in a LoopPlay.
       
  2396      * When User Pauses after LastBufferSent and cancels the TrailingSilenceTimer, UserPlay should automatically kickback the DoRepeats 
       
  2397      */
       
  2398     /*#ifdef    __TRUEPAUSE_SUPPORT__
       
  2399       if (IsLoopPlayEnabled())
       
  2400         { // repeat enabled and last buffer sent but userwe're paused
       
  2401         DP0(_L("CAdvancedAudioPlayController::LastBufferSent iNeedToResumeForRepeat ETrue"));
       
  2402         iNeedToResumeForRepeat = ETrue; // always set in case user pauses - only to be used when resuming from DoPlayL
       
  2403         }
       
  2404       #endif
       
  2405      */
       
  2406     DP0(_L("CAdvancedAudioPlayController::LastBufferSent End"));
       
  2407     }
       
  2408 
       
  2409 void CAdvancedAudioPlayController::DoRepeat()
       
  2410     {
       
  2411     DP0(_L("CAdvancedAudioPlayController::DoRepeat Begin"));
       
  2412     // save the current position, this will be used to calculate the position in loop play when
       
  2413     // client calls for PositionL() or Pause() operations
       
  2414     // TODO:  need to check this position when loop play is going on in a play window
       
  2415     iSavedTimePositionInMicroSecs = iAudioOutput->CalculateAudioOutputPositionL();
       
  2416     DP1(_L("CAdvancedAudioPlayController::DoRepeat iSavedTimePositionInMicroSecs[%u]"), iSavedTimePositionInMicroSecs);
       
  2417     
       
  2418     if ((!iRepeatForever) && (iCurrentRepeatCount < iRepeatCount))
       
  2419         {
       
  2420         iCurrentRepeatCount++;
       
  2421         }
       
  2422     DP1(_L("CAdvancedAudioPlayController::DoRepeat Number of times played till now = %d"), iCurrentRepeatCount);
       
  2423     
       
  2424     if (iSourceIsTimeSeekable || iSourceIsPosSeekable)
       
  2425         { // For seekable source
       
  2426         // if there is a playwindow set then use that, otherwise go back to 0 time
       
  2427         // if ((iPlayWindowStartPosition != 0) || (iPlayWindowEndPosition != 0))
       
  2428         // SetPlayWindow(iPlayWindowStartPosition, iPlayWindowEndPosition);
       
  2429         if (iPlayWindowStartPosition > 0)
       
  2430             {
       
  2431             DP1(_L("CAdvancedAudioPlayController::DoRepeat SetPositionL[%d]ms"), I64LOW(iPlayWindowStartPosition.Int64()/1000));
       
  2432             SetPositionL(iPlayWindowStartPosition);
       
  2433             }
       
  2434         else
       
  2435             {
       
  2436             DP0(_L("CAdvancedAudioPlayController::DoRepeat SetPositionL(0)"));
       
  2437             SetPositionL(0);
       
  2438             }
       
  2439         // Register for PlayWindow end position as the FrameTable has set its playwindowendpostime to zero
       
  2440         if (iPlayWindowEndPosition > 0)
       
  2441             {
       
  2442             DP1(_L("CAdvancedAudioPlayController::DoRepeat iAudioUtility->SetPlayWindowEndTimeMs(%d)"), I64LOW(iPlayWindowEndPosition.Int64()/1000));
       
  2443             iAudioUtility->SetPlayWindowEndTimeMs(iPlayWindowEndPosition.Int64() / 1000);
       
  2444             }
       
  2445         }
       
  2446     else
       
  2447         { // For non-seekable source
       
  2448         // Stop and start playback
       
  2449         DP0(_L("CAdvancedAudioPlayController::DoRepeat Non-Seekable source."));
       
  2450         iAudioOutput->StopL(EFalse);
       
  2451         iDataSourceAdapter->SourceStopL(); // clear the buffers in the source before seeking and priming it
       
  2452         DoInitializeL();
       
  2453         // set the read header flag to true so that the header is read before the playback is resumed
       
  2454         // and the current position is adjusted to be placed after the header.
       
  2455         iReadHeader = ETrue;
       
  2456         }
       
  2457     DP0(_L("CAdvancedAudioPlayController::DoRepeat End") );
       
  2458     }
       
  2459 
       
  2460 EXPORT_C void CAdvancedAudioPlayController::TrailingSilenceTimerComplete()
       
  2461     {
       
  2462     DP0(_L("CAdvancedAudioPlayController::TrailingSilenceTimerComplete "));
       
  2463     DoRepeat();
       
  2464     }
       
  2465 
       
  2466 EXPORT_C TInt CAdvancedAudioPlayController::GetCodecConfigData(RArray<TInt>& aCodecConfigData)
       
  2467     {
       
  2468     TInt stat = KErrNone;
       
  2469     iAudioUtility->SetCodecConfigData(aCodecConfigData);
       
  2470 	iSinkNumChannels = iAudioUtility->ChannelsOut();
       
  2471     return stat;
       
  2472     }
       
  2473 
       
  2474 // -----------------------------------------------------------------------------
       
  2475 // CAdvancedAudioPlayController::Refillbuffer
       
  2476 //
       
  2477 // Called after the data buffer is filled. Update the number of bytes read
       
  2478 // and the current read position for the next read operation.
       
  2479 // -----------------------------------------------------------------------------
       
  2480 //
       
  2481 EXPORT_C TInt CAdvancedAudioPlayController::RefillBuffer(CMMFBuffer* refillBuffer)
       
  2482     {
       
  2483     DP1(_L("CAdvancedAudioPlayController::RefillBuffer: [%x]"),
       
  2484           static_cast<CMMFDataBuffer*>(refillBuffer)->Data().Ptr() );
       
  2485 
       
  2486     // prevent further request        - is this really neccessary
       
  2487     TBool lastBufferSet = EFalse;
       
  2488 	
       
  2489     for (TInt i = 0; i < iSharedBuffers.Count(); i++)
       
  2490         {
       
  2491         if (iSharedBuffers[i]->LastBuffer() && 
       
  2492             (iSharedBuffers[i]->Status() != EBeingFilled)) // need to make sure it is not still held by the source
       
  2493             {
       
  2494             lastBufferSet = ETrue;
       
  2495             break;
       
  2496             }
       
  2497         }
       
  2498 
       
  2499     if (lastBufferSet)
       
  2500         {
       
  2501         // invalidate this buffer
       
  2502         DP1(_L("CAdvancedAudioPlayController::RefillBuffer: marking[%x] EUnavailable and clearing its LB"),
       
  2503                 static_cast<CMMFDataBuffer*>(refillBuffer)->Data().Ptr() );
       
  2504         refillBuffer->SetLastBuffer(EFalse);
       
  2505         refillBuffer->SetStatus(EUnAvailable);
       
  2506         
       
  2507         return KErrCancel;
       
  2508         }
       
  2509 
       
  2510     TRAPD(err, FillSharedBufferL(refillBuffer)); // Trap if DRM read fails
       
  2511 
       
  2512     if (err != KErrNone)
       
  2513         {
       
  2514         DP1(_L("Error filling shared buffer!!! %d"),err);
       
  2515 
       
  2516         iState = EPlaying;          // Set here to get StopL to shutdown completely
       
  2517         TRAP_IGNORE(DoStopL(err));  // If stop leaves, then just return err
       
  2518         }
       
  2519 
       
  2520     return err;
       
  2521     }
       
  2522 
       
  2523 // -----------------------------------------------------------------------------
       
  2524 // CAdvancedAudioPlayController::PlaybackComplete
       
  2525 // -----------------------------------------------------------------------------
       
  2526 //
       
  2527 EXPORT_C void CAdvancedAudioPlayController::PlaybackComplete()
       
  2528     { // comes here for KErrUnderflow - no error
       
  2529     DP3(_L("CAdvancedAudioPlayController::PlaybackComplete() reqstate[%d] state[%d] playseek[%d]"), iRequestState, iState, iPlaySeeking);
       
  2530     // Keep in mind that seek past end of file would end up here instead of SeekPositionReached()
       
  2531     if (iPlaySeeking)
       
  2532         {
       
  2533         // Seeking past end of file.
       
  2534         // Here we should be in play state and iPlaySeeking (playing for seeking purpose)
       
  2535         // Take care of this with the SeekPositionReached method, but don't adjust time.
       
  2536         SeekPositionReached(KMaxTUint);
       
  2537         }
       
  2538     else
       
  2539         { // normal play to end of file
       
  2540         DP0(_L("CAdvancedAudioPlayController::PlaybackComplete() stopping"));
       
  2541         TRAP_IGNORE(DoStopL(KErrUnderflow));
       
  2542         }
       
  2543     }
       
  2544 
       
  2545 // -----------------------------------------------------------------------------
       
  2546 // CAdvancedAudioPlayController::SendEvent
       
  2547 // -----------------------------------------------------------------------------
       
  2548 //
       
  2549 EXPORT_C void CAdvancedAudioPlayController::SendEvent(
       
  2550     const TMMFEvent& aEvent)
       
  2551     {
       
  2552     DP2(_L("CAdvancedAudioPlayController::SendEvent[%d] this[%x]"), aEvent.iErrorCode, this);
       
  2553 
       
  2554 	if (aEvent.iErrorCode == KErrBufferNotReady)
       
  2555 		{
       
  2556         HandleAutoPauseEvent();
       
  2557 		}
       
  2558     // MMFDevSound throws the following error codes incase of any preemption events
       
  2559     // (DevSound instance has been thrown-off or initial request has been rejected)
       
  2560     else if ((aEvent.iErrorCode == KErrAccessDenied) || (aEvent.iErrorCode == KErrInUse) || (aEvent.iErrorCode == KErrDied) )
       
  2561     	{
       
  2562     	// this might be a DevSound Preemption
       
  2563     	// KErrDied is too generic because it is being returned in many situations
       
  2564         HandlePreemptionEvent(aEvent.iErrorCode);
       
  2565     	}
       
  2566 	else
       
  2567 		{
       
  2568 	    HandleGeneralEvent(aEvent);
       
  2569         }
       
  2570     }
       
  2571     
       
  2572 // -----------------------------------------------------------------------------
       
  2573 // CAdvancedAudioPlayController::BitRateChanged
       
  2574 // -----------------------------------------------------------------------------
       
  2575 //
       
  2576 EXPORT_C void CAdvancedAudioPlayController::BitRateChanged()
       
  2577     {
       
  2578     DP0(_L("CAdvancedAudioPlayController::BitRateChanged"));
       
  2579     iDataSourceAdapter->Event(KMultimediaDataSourceEventBitRateChanged);
       
  2580     UpdateDuration(KOneThousandMilliSecond);
       
  2581     }
       
  2582 
       
  2583 // -----------------------------------------------------------------------------
       
  2584 // CAdvancedAudioPlayController::BufferFilled
       
  2585 // -----------------------------------------------------------------------------
       
  2586 //
       
  2587 EXPORT_C void CAdvancedAudioPlayController::BufferFilled(CMMFBuffer* aBuffer)
       
  2588     {
       
  2589 	DP0(_L("CAdvancedAudioPlayController::BufferFilled"));
       
  2590     TRAPD(err, BufferFilledL(aBuffer));
       
  2591     if (err != KErrNone)
       
  2592         {
       
  2593         DP1(_L("CAdvancedAudioPlayController::BufferFilled, BufferFilledL err[%d]"), err);
       
  2594         TRAP_IGNORE(DoStopL(err));
       
  2595         }
       
  2596     }
       
  2597 
       
  2598 // -----------------------------------------------------------------------------
       
  2599 // CAdvancedAudioPlayController::Event
       
  2600 // -----------------------------------------------------------------------------
       
  2601 //
       
  2602 EXPORT_C void CAdvancedAudioPlayController::Event(TUid aEvent)
       
  2603     {
       
  2604     if (iEventsEnabled)
       
  2605         {
       
  2606         if (aEvent == KMultimediaDataSourceObserverEventSourceSizeChanged)
       
  2607             {
       
  2608             TInt sourceSize = iDataSourceAdapter->SourceSize();
       
  2609             if (sourceSize < 0)
       
  2610                 {
       
  2611                 sourceSize = 0;
       
  2612                 }
       
  2613             if (iAudioUtility)
       
  2614             	{
       
  2615         	TRAP_IGNORE(iAudioUtility->SetClipSizeL(sourceSize));
       
  2616             	}
       
  2617             UpdateDuration(0);
       
  2618             }
       
  2619         if (aEvent == KMultimediaDataSourceEventRandomSeekingSupportChanged)
       
  2620             {
       
  2621 			iSourceIsTimeSeekable = iDataSourceAdapter->IsTimeSeekable();
       
  2622 			iSourceIsPosSeekable = iDataSourceAdapter->IsPositonSeekable();
       
  2623             }
       
  2624         }
       
  2625     }
       
  2626     
       
  2627 EXPORT_C void CAdvancedAudioPlayController::SeekPositionReached(TUint aTimeMs)    
       
  2628     {// this can only be called from play state - we have reached this seek time
       
  2629     // update the time played and transition back to correct state
       
  2630 	DP1(_L("CAdvancedAudioPlayController::SeekPositionReached[%d]"), aTimeMs);
       
  2631 	if (aTimeMs < KMaxTUint)
       
  2632 	    { // no update if seek past end of file - this comes from playbackcomplete()
       
  2633 	    iTimePositionInMicroSecs = aTimeMs; // this is set before the seek - may not need to do this here
       
  2634 	    iTimePositionInMicroSecs *=1000;
       
  2635         DP1(_L("CAdvancedAudioPlayController::SeekPositionReached iTimePositionInMicroSecs[%d]"),aTimeMs);
       
  2636 	    }
       
  2637     
       
  2638 	iPlaySeeking = EFalse;
       
  2639     if (iPlayingForDuration)
       
  2640         {
       
  2641         UpdateDuration();
       
  2642 		if (iRequestState == EPlaying)
       
  2643 			{ // since we are already playing for the seek and the requested is to play, we can just keep playing
       
  2644 	    	// rendering will be enabled when position reached so we don't have to call play here - we're already playing
       
  2645 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForDuration - not stopping"));
       
  2646 			iPlayingForDuration = EFalse;
       
  2647 			}
       
  2648 		else
       
  2649 			{ // normally this would need to go back to stop state.
       
  2650 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForDuration - stopping"));
       
  2651 	        TRAP_IGNORE(DoStopL(KErrNone));
       
  2652 			}
       
  2653         }
       
  2654     else if (iPlayingForInitPos)
       
  2655         {
       
  2656 		if (iRequestState == EPlaying)
       
  2657 			{ // since we are already playing for the seek and the requested is to play, we can just keep playing
       
  2658 	    	// rendering will be enabled when position reached so we don't have to call play here - we're already playing
       
  2659 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForInitPos - not pausing"));
       
  2660 			iPlayingForInitPos = EFalse;
       
  2661 			}
       
  2662 		else
       
  2663 			{ // normally this would need to go back to pause state.
       
  2664 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForInitPos - pausing"));
       
  2665 	        TRAP_IGNORE(DoPauseL());
       
  2666 			}
       
  2667         }
       
  2668     else if (iPausingForSetPos)
       
  2669     	{ // seek was initiated during play but paused in order to seek and are now returning to play
       
  2670     	// rendering will be enabled when position reached so we don't have to call play here - we're already playing
       
  2671 		DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPausingForSetPos - already playing - rendering should be enabled"));
       
  2672     	iPausingForSetPos = EFalse;
       
  2673         if (iState == EPaused)
       
  2674             {
       
  2675             if (iAudioOutput->IsDSStopped())
       
  2676                 { // during loop play the output is not stopped unless we did a seek - seek stops the output and we need to call DoPlay
       
  2677                 DP0(_L("CAdvancedAudioPlayController::SeekPositionReached Calling DoPlay iState=EPaused"));
       
  2678                 DoPlayL();
       
  2679                 }
       
  2680             else
       
  2681                 {
       
  2682                 DP1(_L("CAdvancedAudioPlayController::SeekPositionReached Calling DoResume iState=EPaused iCurrentPosition[%d]"), iCurrentPosition);
       
  2683                 if (IsLoopPlayEnabled())
       
  2684                     {
       
  2685                     DoResume(iCurrentPosition);
       
  2686                     }
       
  2687                 else
       
  2688                     {
       
  2689                     DoPlayL();
       
  2690                     }
       
  2691                 }
       
  2692             }
       
  2693     	}
       
  2694     else if (iPlayingForPauseSeek)
       
  2695         { // seek was initiated during a pause
       
  2696 		if (iRequestState == EPlaying)
       
  2697 			{ // since we are already playing for the seek and the requested is to play, we can just keep playing
       
  2698 	    	// rendering will be enabled when position reached so we don't have to call play here - we're already playing
       
  2699 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForPauseSeek - not pausing"));
       
  2700 			iPlayingForPauseSeek = EFalse;
       
  2701 			}
       
  2702 		else
       
  2703 			{ // normally this would need to go back to pause state.
       
  2704 			DP0(_L("CAdvancedAudioPlayController::SeekPositionReached iPlayingForPauseSeek - pausing"));
       
  2705 	        TRAP_IGNORE(DoPauseL());
       
  2706 			}
       
  2707         }
       
  2708 	if (iBlockSetPos)
       
  2709 		{
       
  2710 		DP0(_L("CAdvancedAudioPlayController::SeekPositionReached() unblocking"));
       
  2711 		if (iBlockSetPos->IsStarted())
       
  2712 		    {
       
  2713 		    iBlockSetPos->AsyncStop();
       
  2714 		    }
       
  2715 		}
       
  2716     }
       
  2717 
       
  2718 EXPORT_C void CAdvancedAudioPlayController::PlayWindowEndPositionReached()    
       
  2719     {
       
  2720     }
       
  2721     
       
  2722 TBool CAdvancedAudioPlayController::IsLoopPlayEnabled() const
       
  2723     {
       
  2724     if ((iRepeatForever) || (iCurrentRepeatCount <= iRepeatCount))
       
  2725         {
       
  2726         return ETrue;
       
  2727         }
       
  2728     else
       
  2729         {
       
  2730         return EFalse;
       
  2731         }
       
  2732     }
       
  2733 
       
  2734 // --------------------------------------------------------------------------------------------------------------
       
  2735 // CTrailingSilenceTimer class definitions
       
  2736 // --------------------------------------------------------------------------------------------------------------
       
  2737 CTrailingSilenceTimer* CTrailingSilenceTimer::NewL(MTrailingSilenceObserver &aobserver)
       
  2738     {
       
  2739     DP0(_L("CTrailingSilenceTimer::NewL Begin"));
       
  2740     CTrailingSilenceTimer* self=new(ELeave) CTrailingSilenceTimer(aobserver);
       
  2741     CleanupStack::PushL(self);
       
  2742     self->ConstructL();
       
  2743     CleanupStack::Pop();
       
  2744     DP0(_L("CTrailingSilenceTimer::NewL End"));
       
  2745     return self;
       
  2746     }
       
  2747 
       
  2748 CTrailingSilenceTimer::CTrailingSilenceTimer(MTrailingSilenceObserver &aobserver)
       
  2749     :
       
  2750     CTimer(CActive::EPriorityStandard),
       
  2751     iObserver(&aobserver)
       
  2752     {
       
  2753     }
       
  2754 
       
  2755 void CTrailingSilenceTimer::ConstructL()
       
  2756     {
       
  2757     DP0(_L("CTrailingSilenceTimer::ConstructL Begin"));
       
  2758     // Base class second-phase construction.
       
  2759     CTimer::ConstructL();
       
  2760     // Add to the ActiveScheduler
       
  2761     CActiveScheduler::Add(this);
       
  2762     DP0(_L("CTrailingSilenceTimer::ConstructL End"));
       
  2763     }
       
  2764 
       
  2765 CTrailingSilenceTimer::~CTrailingSilenceTimer()
       
  2766     {
       
  2767     DP0(_L("CTrailingSilenceTimer::~CTrailingSilenceTimer Begin"));
       
  2768     Cancel();
       
  2769     DP0(_L("CTrailingSilenceTimer::~CTrailingSilenceTimer End"));
       
  2770     }
       
  2771 
       
  2772 void CTrailingSilenceTimer::DoCancel()
       
  2773     {
       
  2774     DP0(_L("CTrailingSilenceTimer::DoCancel Begin"));
       
  2775     // Call the default DoCancel method
       
  2776     CTimer::DoCancel();
       
  2777     DP0(_L("CTrailingSilenceTimer::DoCancel End"));
       
  2778     }
       
  2779 
       
  2780 void CTrailingSilenceTimer::RunL()
       
  2781     {
       
  2782     DP0(_L("CTrailingSilenceTimer::RunL"));
       
  2783     iObserver->TrailingSilenceTimerComplete();
       
  2784     }
       
  2785 
       
  2786 void CTrailingSilenceTimer::RunError()
       
  2787     {
       
  2788     DP0(_L("CTrailingSilenceTimer::RunError"));
       
  2789     // Handle error here tbd
       
  2790     }
       
  2791 // --------------------------------------------------------------------------------------------------------------
       
  2792 
       
  2793 // End of file