mmfenh/advancedaudiocontroller/wavplaycontrollerplugin/src/MmfAudioController.cpp
changeset 0 71ca22bcf22a
child 54 53984cc2f70a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2005-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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <mmfformat.h>
       
    21 #include <mmfclip.h>
       
    22 #include <mdaaudiosampleeditor.h>
       
    23 #include <mmfcontrollerimplementationuids.hrh>
       
    24 #include <mmffourcc.h>
       
    25 #include <mmfpaniccodes.h>
       
    26 #include "MmfAudioController.h"
       
    27 #include "mmffile.h"
       
    28 #include <mmf/server/mmfformatstandardcustominterfaces.h>
       
    29 #include "devsoundstandardcustominterfaces.h"
       
    30 #include "CustomInterfaceBuilder.h"
       
    31 #include "CustomInterfaceCustomCommandParser.h"
       
    32 #include <mmfdatapath2.h>
       
    33 #include <ConfigurationComponentsFactory.h>
       
    34 #include <AudioOutputControlUtility.h>
       
    35 
       
    36 const TUint KSampleRate8000Hz = 8000;
       
    37 const TUint KSampleRate11025Hz = 11025;
       
    38 const TUint KSampleRate12000Hz = 12000;
       
    39 const TUint KSampleRate16000Hz = 16000;
       
    40 const TUint KSampleRate22050Hz = 22050;
       
    41 const TUint KSampleRate24000Hz = 24000;
       
    42 const TUint KSampleRate32000Hz = 32000;
       
    43 const TUint KSampleRate44100Hz = 44100;
       
    44 const TUint KSampleRate48000Hz = 48000;
       
    45 const TUint KSampleRate64000Hz = 64000;
       
    46 const TUint KSampleRate88200Hz = 88200;
       
    47 const TUint KSampleRate96000Hz = 96000;
       
    48 const TUint KNumChannelsMono = 1;
       
    49 const TUint KNumChannelsStereo = 2;
       
    50 
       
    51 /*
       
    52  TMmfAudioControllerPanics is an enumeration with the following entries:
       
    53  EBadArgument indicates a bad argument
       
    54  EBadState indicates a state viaolation
       
    55  EBadInvariant indicates an invariant violation
       
    56  EBadReset indicates failed reset
       
    57  EPostConditionViolation indicates a post condition violation
       
    58 */
       
    59 enum TMmfAudioControllerPanics
       
    60 	{
       
    61 	EBadArgument,
       
    62 	EBadState,
       
    63 	EBadInvariant,
       
    64 	EBadReset,
       
    65 	EPostConditionViolation
       
    66 	};
       
    67 
       
    68 /**
       
    69 This method generates a panic
       
    70 
       
    71 @param aPanicCode
       
    72 */
       
    73 void Panic(TInt aPanicCode)
       
    74 	{
       
    75 	_LIT(KMMFAudioControllerPanicCategory, "MMFAudioController");
       
    76 	User::Panic(KMMFAudioControllerPanicCategory, aPanicCode);
       
    77 	}
       
    78 
       
    79 /**
       
    80  * Static NewL
       
    81  *
       
    82  * @return CMMFAudioController*
       
    83  */
       
    84 CMMFController* CMMFAudioController::NewL()
       
    85 	{
       
    86 	CMMFAudioController* self = new(ELeave) CMMFAudioController;
       
    87 	CleanupStack::PushL(self);
       
    88 	self->ConstructL();
       
    89 	CleanupStack::Pop( self );
       
    90 	return STATIC_CAST( CMMFController*, self );
       
    91 	}
       
    92 
       
    93 /**
       
    94 * ConstructL
       
    95 *
       
    96 */
       
    97 void CMMFAudioController::ConstructL()
       
    98 	{
       
    99 	iDataSource         = NULL;
       
   100 	iDataSink           = NULL;
       
   101 	iDataPath           = CMMFDataPath2::NewL(iMediaId, *this);
       
   102 	iSourceFormat       = NULL;
       
   103 	iSinkFormat         = NULL;
       
   104 	iSourceAndSinkAdded = EFalse;
       
   105 	iStoppingRecording  = EFalse;
       
   106 	iStoppingPlaying 	= EFalse;
       
   107 
       
   108 	//iMediaId has already been set up
       
   109 	SetState( EStopped );
       
   110 	//iPrioritySettings  not initialised because they are held by the controller framework
       
   111 
       
   112 	// Construct custom command parsers
       
   113 	CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser = CMMFAudioPlayDeviceCustomCommandParser::NewL(*this);
       
   114 	CleanupStack::PushL(audPlayDevParser);
       
   115 	AddCustomCommandParserL(*audPlayDevParser);
       
   116 	CleanupStack::Pop( audPlayDevParser );
       
   117 
       
   118 	CMMFAudioRecordDeviceCustomCommandParser* audRecDevParser = CMMFAudioRecordDeviceCustomCommandParser::NewL(*this);
       
   119 	CleanupStack::PushL(audRecDevParser);
       
   120 	AddCustomCommandParserL(*audRecDevParser);
       
   121 	CleanupStack::Pop(audRecDevParser);
       
   122 
       
   123 	CMMFAudioPlayControllerCustomCommandParser* audPlayConParser = CMMFAudioPlayControllerCustomCommandParser::NewL(*this);
       
   124 	CleanupStack::PushL(audPlayConParser);
       
   125 	AddCustomCommandParserL(*audPlayConParser);
       
   126 	CleanupStack::Pop(audPlayConParser);
       
   127 
       
   128 	CMMFAudioRecordControllerCustomCommandParser* audRecConParser = CMMFAudioRecordControllerCustomCommandParser::NewL(*this);
       
   129 	CleanupStack::PushL(audRecConParser);
       
   130 	AddCustomCommandParserL(*audRecConParser);
       
   131 	CleanupStack::Pop(audRecConParser);
       
   132 
       
   133 	CMMFAudioControllerCustomCommandParser* audConParser = CMMFAudioControllerCustomCommandParser::NewL(*this);
       
   134 	CleanupStack::PushL(audConParser);
       
   135 	AddCustomCommandParserL(*audConParser);
       
   136 	CleanupStack::Pop(audConParser);
       
   137 
       
   138 #ifdef SYMBIAN_CAF_V2
       
   139 	CMMFDRMCustomCommandParser* drmParser = CMMFDRMCustomCommandParser::NewL(*this);
       
   140 	CleanupStack::PushL(drmParser);
       
   141 	AddCustomCommandParserL(*drmParser);
       
   142 	CleanupStack::Pop(drmParser);
       
   143 #endif
       
   144 
       
   145 	CMMFResourceNotificationCustomCommandParser* NotiParser = CMMFResourceNotificationCustomCommandParser::NewL(*this);
       
   146 	CleanupStack::PushL(NotiParser);
       
   147 	AddCustomCommandParserL(*NotiParser);
       
   148 	CleanupStack::Pop(NotiParser);//audio resource Notification Parser
       
   149 
       
   150 	CCustomInterfaceCustomCommandParser* customInterfaceParser = CCustomInterfaceCustomCommandParser::NewL(*this);
       
   151 	CleanupStack::PushL(customInterfaceParser);
       
   152 	AddCustomCommandParserL(*customInterfaceParser);
       
   153     CleanupStack::Pop(customInterfaceParser);
       
   154 
       
   155 	CMMFAudioPlayControllerSetRepeatsCustomCommandParser* audPlayConSetRepeatsParser = CMMFAudioPlayControllerSetRepeatsCustomCommandParser::NewL(*this);
       
   156 	CleanupStack::PushL(audPlayConSetRepeatsParser);
       
   157 	AddCustomCommandParserL(*audPlayConSetRepeatsParser);
       
   158 	CleanupStack::Pop(audPlayConSetRepeatsParser);
       
   159 
       
   160     TInt err = CConfigurationComponentsFactory::CreateFactoryL(iFactory);
       
   161     User::LeaveIfError(err);    
       
   162     
       
   163     if (iFactory)
       
   164         {
       
   165         err = iFactory->CreateAudioOutputControlUtility(iAudioOutputControlUtility);
       
   166         User::LeaveIfError(err);                
       
   167         }    
       
   168 	// [ assert the invariant now that we are constructed ]
       
   169 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
   170 	}
       
   171 
       
   172 /**
       
   173 *
       
   174 * CMMFAudioController
       
   175 *
       
   176 */
       
   177 
       
   178 CMMFAudioController::CMMFAudioController()
       
   179 	: iMediaId(KUidMediaTypeAudio),
       
   180 	  iDisableAutoIntent(EFalse),
       
   181       iState(EStopped)
       
   182 	{
       
   183 	}
       
   184 
       
   185 /**
       
   186 *
       
   187 * ~CMMFAudioController
       
   188 *
       
   189 */
       
   190 
       
   191 CMMFAudioController::~CMMFAudioController()
       
   192 	{
       
   193 	// [ ensure we have logged off the thread ]
       
   194     if(iAudioOutputControlUtility)
       
   195         delete iAudioOutputControlUtility;
       
   196     if(iFactory)
       
   197         delete iFactory;
       
   198 	if( iDataPath )
       
   199 		{
       
   200 		TRAP_IGNORE(iDataPath->ResetL());	// this does not leave
       
   201 		}
       
   202 	delete iDataPath;
       
   203 	delete iSourceFormat;
       
   204 	delete iSinkFormat;
       
   205 	delete iStoppingMessage;
       
   206     }
       
   207 
       
   208 /**
       
   209  *  AddDataSourceL
       
   210  *
       
   211  *	Adds a data source to the controller
       
   212  *
       
   213  *	@param aSource
       
   214  * Preconditions:
       
   215  * We are stopped
       
   216  * Source does not already exist
       
   217  * Postconditions:
       
   218  * iDataSource != NULL
       
   219  * iDataSourceAdded == ETrue
       
   220  */
       
   221 void CMMFAudioController::AddDataSourceL(MDataSource& aSource)
       
   222 	{
       
   223 	//[ assert the invariant ]
       
   224 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
   225 
       
   226 	// [ precondition that the controller is stopped ]
       
   227     if( State() != EStopped )
       
   228 		User::Leave( KErrNotReady );
       
   229 
       
   230 	//[ precondition iData source is not already configured ]
       
   231 	if (iDataSource)
       
   232 		User::Leave(KErrAlreadyExists);
       
   233 
       
   234 	// Note that this code is not generic for sources
       
   235 	// It it only checks for file, des clips and audio inputs
       
   236 	// If a new source type eg a Url Clip then this needs to be added to the supported source Uids
       
   237 	if ( SourceFormatRequired( aSource) )
       
   238 		{
       
   239 		// Get the format from the Source if possible from no specific supplier
       
   240 		TRAPD(err, iSourceFormat = CMMFFormatDecode::NewL(&aSource, KNullDesC, iSourceFormatSupportsCustomInterfaces));
       
   241 		//[ we want to complete silently for KErrNotSupported
       
   242 		// because there is a possibility that the client
       
   243 		// wants to add the data format later, see audio api for
       
   244 		// a description of this feature]
       
   245 		if ((err != KErrNotSupported) && (err != KErrNone))
       
   246 			{
       
   247 			User::Leave(err);
       
   248 			}
       
   249 		}
       
   250 	else if (aSource.DataSourceType()==KUidMmfAudioInput)
       
   251 		{
       
   252 		//[ ensure that the audio input has a pointer to dev sound ]
       
   253 		CMMFAudioInput* audioInput = STATIC_CAST(CMMFAudioInput*, &aSource);
       
   254 		__ASSERT_ALWAYS( audioInput, Panic(EBadInvariant));
       
   255 		// [ lets load dev sound ]
       
   256 		User::LeaveIfError(audioInput->SourceThreadLogon( *this ));
       
   257 		}
       
   258 	else
       
   259 		{
       
   260 		User::Leave(KErrNotSupported);
       
   261 		}
       
   262 
       
   263 	//[ its now safe to set the source ]
       
   264 	iDataSource = &aSource ;
       
   265 	iDataSource->SetSourcePrioritySettings(iPrioritySettings);
       
   266 
       
   267 	//[ assert the post condition ]
       
   268 	__ASSERT_ALWAYS(iDataSource, Panic(EMMFAudioControllerPanicDataSourceDoesNotExist));
       
   269 
       
   270 	}
       
   271 
       
   272 
       
   273 /**
       
   274  *  AddDataSinkL
       
   275  *
       
   276  *	Adds a data sink to the controller
       
   277  *
       
   278  *	@param aSink
       
   279  *
       
   280  */
       
   281 void CMMFAudioController::AddDataSinkL(MDataSink& aSink)
       
   282 	{
       
   283 	//[ assert the invariant ]
       
   284 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
   285 
       
   286 	// [ precondition that the controller is stopped ]
       
   287     if( State() != EStopped )
       
   288 		User::Leave( KErrNotReady );
       
   289 
       
   290 	// [ assert precondition that sink does not exist ]
       
   291 	if (iDataSink)
       
   292 		User::Leave(KErrAlreadyExists);
       
   293 
       
   294 
       
   295 	// Note that this code is not generic for sinks
       
   296 	// It it only checks for file,des clips and audio outputs
       
   297 	// If a new sink type eg a Url Clip then this needs to be added to the supported source Uids
       
   298 	if ( SinkFormatRequired( aSink ) )
       
   299 		{//the sink is a clip
       
   300 
       
   301 		// Get the format from the Sink if possible from no specific supplier
       
   302 		TRAPD(err, iSinkFormat = CMMFFormatEncode::NewL(&aSink, KNullDesC));
       
   303 		//[ we want to complete silently for KErrNotSupported
       
   304 		// because there is a possibility that the client
       
   305 		// wants to add the data format later, see audio api for
       
   306 		// a description of this feature]
       
   307 		if ((err != KErrNotSupported) && (err != KErrNone))
       
   308 			{
       
   309 			User::Leave(err);
       
   310 			}
       
   311 		}
       
   312 	else if (aSink.DataSinkType()==KUidMmfAudioOutput)
       
   313 		{
       
   314 
       
   315 		//[ ensure that the audio output has a pointer to dev sound ]
       
   316 		CMMFAudioOutput* audioOutput = STATIC_CAST(CMMFAudioOutput*, &aSink);
       
   317 		__ASSERT_ALWAYS( audioOutput, Panic(EBadInvariant));
       
   318 		// [ lets load dev sound ]
       
   319 		User::LeaveIfError(audioOutput->SinkThreadLogon( *this ));
       
   320 		audioOutput->SoundDevice().SetClientThreadInfo(ClientThreadIdL());
       
   321 		}
       
   322 	else
       
   323 		{
       
   324 		User::Leave(KErrNotSupported);
       
   325 		}
       
   326 
       
   327 	//[ now that we are sure we have not left we can update the sink
       
   328 	// transactionally ]
       
   329 	iDataSink = &aSink;
       
   330 	iDataSink->SetSinkPrioritySettings(iPrioritySettings);
       
   331 
       
   332 	// [ assert post conditions that a sink has been added ]
       
   333 	__ASSERT_ALWAYS(iDataSink, Panic(EMMFAudioControllerPanicDataSinkDoesNotExist));
       
   334 
       
   335 	}
       
   336 
       
   337 /**
       
   338  *  PrimeL
       
   339  *
       
   340  *  If Prime fails the client should reset the controller
       
   341  *  because as noted below this code is not transactional.
       
   342  *
       
   343  */
       
   344 void CMMFAudioController::PrimeL()
       
   345 	{
       
   346 	//[ assert the invariant ]
       
   347 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
   348 
       
   349 	//[ assert the precondition ( in a friendly way for this api
       
   350 	// that we are either stopped or primed already ]
       
   351 	if(!(( State() == EStopped ) || (State() == EPrimed )))
       
   352 		User::Leave( KErrNotReady );
       
   353 
       
   354 	// [ precondition we have a data source & sink ]
       
   355 	__ASSERT_ALWAYS( iDataSource, Panic( EBadInvariant));
       
   356 	__ASSERT_ALWAYS( iDataSink, Panic( EBadInvariant));
       
   357 
       
   358 
       
   359 	//[ precondition that we need a source format ]
       
   360 	if ( SourceFormatRequired(*iDataSource) && !(iSourceFormat))
       
   361 		User::Leave( KErrNotSupported );
       
   362 
       
   363 	// [ check the precondition if we need a data sink format ]
       
   364 	if ( SinkFormatRequired(*iDataSink) && !( iSinkFormat ))
       
   365 		{
       
   366 		User::Leave( KErrNotSupported );
       
   367 		}
       
   368 
       
   369 	// [ ideally this code should be transaction based and
       
   370 	//   if failure occurs we roll back to the previous state
       
   371 	// in the code below this is not the case and the controller
       
   372 	// can be left in an unstable state should any part of prime fail]
       
   373 	if (iState == EStopped)
       
   374 		{ //datapath propagates prime to sink & source
       
   375 
       
   376 		NegotiateL();
       
   377 
       
   378 		if (!iSourceAndSinkAdded)
       
   379 			{
       
   380 			//add data source and sinks to datapath - Note cant do this in AddDataSource/Sink
       
   381 			//because the sources and sinks aren't configured at this point
       
   382 			if (iSourceFormat)
       
   383 				iDataPath->AddDataSourceL(iSourceFormat);
       
   384 			else if (iDataSource)
       
   385 				iDataPath->AddDataSourceL(iDataSource);
       
   386 			if (iSinkFormat)
       
   387 				iDataPath->AddDataSinkL(iSinkFormat);
       
   388 			else if (iDataSink)
       
   389 				iDataPath->AddDataSinkL(iDataSink);
       
   390 			iSourceAndSinkAdded = ETrue ;
       
   391 			}
       
   392 
       
   393 		iDataPath->PrimeL();
       
   394 		if (iSourceFormat)
       
   395 			{
       
   396 			//in case of imaadpcm format set the output block length
       
   397 			
       
   398 			TFourCC sourceFourCC = iSourceFormat->SourceDataTypeCode(TMediaId(KUidMediaTypeAudio));
       
   399 			if ((sourceFourCC == KMMFFourCCCodeIMAD) && iSourceFormatSupportsCustomInterfaces)
       
   400 				{
       
   401 				CMMFFormatDecode2* decode2 = static_cast<CMMFFormatDecode2*>(iSourceFormat);
       
   402 				MMMFDecodeCustomInterfaceBlockLength* formatBlockLengthCI = static_cast<MMMFDecodeCustomInterfaceBlockLength*>(decode2->CustomInterface(KUidCustomInterfaceMmfDecodeBlockLength));
       
   403 				if (formatBlockLengthCI)
       
   404 					{
       
   405 					TInt blockLength = formatBlockLengthCI->FileBlockLength();
       
   406 					
       
   407 					//********** Symbian Change.
       
   408 					//TInt err = KErrNotSupported;
       
   409 					//if (iSinkFormat)
       
   410 					//	{
       
   411 					//	err = iDataPath->SetBlockLength(blockLength);
       
   412 					//	}
       
   413 					//************
       
   414 					TInt err = iDataPath->SetBlockLength(blockLength); 
       
   415 					
       
   416 					if ((err != KErrNone) && (iDataSink))
       
   417 						{
       
   418 						MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
   419 						MMMFDevSoundCustomInterfaceFileBlockLength* fileBlockLengthCI = static_cast<MMMFDevSoundCustomInterfaceFileBlockLength*>(audioOutput->SoundDevice().CustomInterface(KUidCustomInterfaceDevSoundFileBlockLength));
       
   420 
       
   421 						if (fileBlockLengthCI)
       
   422 							{
       
   423 							fileBlockLengthCI->SetFileBlockLength(blockLength);
       
   424 							err = KErrNone;
       
   425 							}
       
   426 						}
       
   427 					User::LeaveIfError(err);
       
   428 					}
       
   429 				}
       
   430 			}
       
   431 			
       
   432 		if ((iSinkFormat) && (!iSourceFormat))
       
   433 			{//we are recording to a clip so the data path position is the sink
       
   434 			//need to set datapath position to end of format pos (incase sink clip already exists
       
   435 			TTimeIntervalMicroSeconds duration = iSinkFormat->Duration(iMediaId);
       
   436 			if (duration != TTimeIntervalMicroSeconds(0))
       
   437 				{//the file already exists and has a duration so set data path position to the end of the file
       
   438 				iDataPath->SetPositionL(duration);
       
   439 				}
       
   440 			}
       
   441 		//[ it is now safe to make the transition to primed ]
       
   442 		SetState( EPrimed );
       
   443 		}
       
   444 	else if (State() == EPrimed)
       
   445 		{ //controller is already primed so just pass prime onto DP
       
   446 		iDataPath->PrimeL();
       
   447 		}
       
   448 
       
   449 	if (iDataSource->DataSourceType()==KUidMmfFileSource)
       
   450 		{
       
   451 		CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   452 		// we only support protected files for playback
       
   453         if (file->IsProtectedL())
       
   454             {
       
   455             if (iDataSink->DataSinkType()!=KUidMmfAudioOutput)
       
   456                 {
       
   457                 User::Leave(KErrNotSupported);
       
   458                 }
       
   459             TInt err;
       
   460             err = iAudioOutputControlUtility->SetDataSource(iDataSource);
       
   461             if (err != KErrNone)
       
   462                 {
       
   463                 User::Leave(err);
       
   464                 }
       
   465             }            
       
   466         }
       
   467 
       
   468 	//[ assert the post condition that we are in the state primed]
       
   469 	__ASSERT_ALWAYS( SetState( EPrimed ), Panic( EPostConditionViolation ));
       
   470 	// [ assert the invariant]
       
   471 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ) );
       
   472 	}
       
   473 
       
   474 /**
       
   475  *  ResetL
       
   476  *  This method resets the controller
       
   477  *
       
   478  */
       
   479 void CMMFAudioController::ResetL()
       
   480 	{
       
   481 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ) );
       
   482 
       
   483 	// Stop recording if it's not stopped,
       
   484 	if (State() != EStopped)
       
   485 		{
       
   486 		iDataPath->Stop();
       
   487 		SetState(EStopped);
       
   488 		}
       
   489 	iIsPaused = EFalse;
       
   490 
       
   491 	// Remove references to source and sink
       
   492 	iDataPath->ResetL();
       
   493 
       
   494 	delete iSourceFormat; iSourceFormat = NULL  ;
       
   495 	delete iSinkFormat;	iSinkFormat = NULL  ;
       
   496 
       
   497 	//[ ensure loggoff of source and sink ]
       
   498 	iDataSource = NULL ;
       
   499 	iDataSink = NULL ;
       
   500 	iSourceAndSinkAdded = EFalse;
       
   501 
       
   502 	// [ assert the invariant]
       
   503 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ) );
       
   504 
       
   505 	// [ assert the post condition
       
   506 	//   state == stopped
       
   507 	//   iDataSource is NULL
       
   508 	//   iSourceFormat is NULL
       
   509 	//   iSinkFormat is NULL ]
       
   510 	__ASSERT_ALWAYS( ResetPostCondition(), Panic( EBadReset ));
       
   511 	__ASSERT_ALWAYS( Invariant(), Panic(EBadState));
       
   512 	}
       
   513 
       
   514 /**
       
   515 * ResetPostCondition
       
   516 * This function determnines if the reset post condition is valid
       
   517 * @internalTechnology
       
   518 */
       
   519 TBool CMMFAudioController::ResetPostCondition() const
       
   520 	{
       
   521 
       
   522      TBool result = EFalse ;
       
   523 	if((iSourceFormat     == NULL)  &&
       
   524 	(iDataSink            == NULL)  &&
       
   525 	(iDataSource          == NULL)  &&
       
   526 	(iSinkFormat          == NULL)  &&
       
   527 	(State() == EStopped))
       
   528 		{
       
   529          result = ETrue;
       
   530 		}
       
   531 
       
   532     return result;
       
   533 	}
       
   534 
       
   535 
       
   536 /**
       
   537  *
       
   538  * PlayL
       
   539  *
       
   540  */
       
   541 void CMMFAudioController::PlayL()
       
   542 	{
       
   543 	// [ assert the precondition that the
       
   544 	//   play command is only activated in the primed state]
       
   545 	if ( State() != EPrimed)
       
   546 		{
       
   547 		User::Leave(KErrNotReady);
       
   548 		}
       
   549 
       
   550 	// [ assert the Invariant ]
       
   551 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   552 
       
   553 	// if the position has already been set to the file's duration or
       
   554 	// beyond, then don't bother getting the datapath to play - this
       
   555 	// avoids sending empty buffers to DevSound
       
   556 	if (iDataSink->DataSinkType() == KUidMmfAudioOutput &&
       
   557 		PositionL() >= DurationL())
       
   558 		{
       
   559 		SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrNone));
       
   560 		return;
       
   561 		}
       
   562 
       
   563 	// Execute play intent
       
   564 	// This must be done after PlayL, as the file might not be open yet
       
   565 	// In case of system preemption (like audio is preempted by voice call)ExecuteIntent should not be called.
       
   566 	if(!iIsPreemptionPause)
       
   567 		{
       
   568 		if (!iDisableAutoIntent && iDataSource->DataSourceType()==KUidMmfFileSource)
       
   569 			{
       
   570 			CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   571 			TInt err = file->ExecuteIntent(iIsPaused? ContentAccess::EContinue : ContentAccess::EPlay);
       
   572 			if (err != KErrNone)
       
   573 				{
       
   574 				User::Leave(err);
       
   575 				}
       
   576 			}
       
   577 		}
       
   578 	//[datapath propogates play to sink & source]
       
   579 	if(iIsPaused)
       
   580 	    {
       
   581 	    iDataPath->RetainRepeatInfo();
       
   582 	    }
       
   583 		
       
   584 	//configure Devsound with output restriction for a DRM protected file
       
   585 	if (iDataSource->DataSourceType()==KUidMmfFileSource)
       
   586         {
       
   587         CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   588         // we only support protected files for playback
       
   589         if (file->IsProtectedL())
       
   590             {
       
   591             MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
   592             iAudioOutputControlUtility->Configure(audioOutput->SoundDevice());    //ignoring errors since rouitng changes are only suggestions to adaptation
       
   593             }
       
   594         }
       
   595 	iDataPath->PlayL();
       
   596 	iIsPreemptionPause = EFalse;
       
   597 	iIsPaused = EFalse;
       
   598 	SetState( EPlaying );
       
   599 
       
   600 	//[ assert the post condition we are playing ]
       
   601 	//No - this assumption is not always true if an error occurs eg OOM
       
   602 	//the state could be EStopped
       
   603 	//	__ASSERT_ALWAYS( (State() == EPlaying ), Panic( EBadState));
       
   604 	//[ assert the invariant ]
       
   605 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   606 	}
       
   607 
       
   608 /**
       
   609  *  PauseL
       
   610  *
       
   611  */
       
   612 void CMMFAudioController::PauseL()
       
   613 	{
       
   614 	// [ assert the invariant ]
       
   615 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   616 
       
   617 	//[ assert the precondition that we are playing ]
       
   618 	if ( State() != EPlaying)
       
   619 		{
       
   620 		User::Leave(KErrNotReady);
       
   621 		}
       
   622 	// In case of system preemption (like audio is preempted by voice call)ExecuteIntent should not be called.	
       
   623 	if(!iIsPreemptionPause)
       
   624 		{
       
   625 		if (!iDisableAutoIntent && iDataSource->DataSourceType()==KUidMmfFileSource)
       
   626 			{
       
   627 			CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   628 			TInt err = file->ExecuteIntent(ContentAccess::EPause);
       
   629 			if (err != KErrNone)
       
   630 				{
       
   631 				User::Leave(err);
       
   632 				}
       
   633 			}
       
   634 		}
       
   635 	iIsPaused = ETrue;
       
   636 	//[ datapath propogates pause to sink & source ]
       
   637 	if(iIsPreemptionPause)
       
   638 		{
       
   639 		iDataPath->PreEmptionPause();
       
   640 		}
       
   641 	else
       
   642 		{
       
   643 		iDataPath->Pause();
       
   644 		}
       
   645 		
       
   646 	SetState(EPrimed);
       
   647 
       
   648 	//[ assert the post condition we are primed ]
       
   649 	__ASSERT_ALWAYS( (State() == EPrimed ), Panic( EBadState));
       
   650 	//[ assert the invariant ]
       
   651 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   652 	}
       
   653 
       
   654 /**
       
   655  *  StopL
       
   656  *
       
   657  */
       
   658 void CMMFAudioController::StopL(TMMFMessage& aMessage)
       
   659 	{
       
   660 	//[ assert the invariant ]
       
   661 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   662 	// [ precondition that we are not already stopped
       
   663 	// && if we are stopped do nothing.
       
   664 	//If we are stopping a recording, we need to give the datapath chance to
       
   665 	//process that data which has already been captured. We therefore stay in the EPlaying
       
   666 	//state, but use iStoppingRecording to indicate that we are stopping.
       
   667 
       
   668 	if ((State() != EStopped) && !iStoppingRecording && !iStoppingPlaying)
       
   669 		{
       
   670 		if((State() == EPlaying) && (iDataSource->DataSourceType()==KUidMmfAudioInput)) //we are recording
       
   671 			{
       
   672 			// datapath is requested to stop recording but process any alreay captured buffers,
       
   673 			// the pause method is used for this purpose and as such, the data path must
       
   674 			// determine that it is recording to be able to act accordingly.
       
   675 			// aMessgae is not completed until datapath advises that it has completed.
       
   676 			iDataPath->Pause();
       
   677 			iStoppingMessage = CMMFMessageHolder::NewL(aMessage);
       
   678 			iStoppingRecording = ETrue;
       
   679 			}
       
   680 		else if(((State() == EPlaying) || iIsPaused) && (iDataSink->DataSinkType()==KUidMmfAudioOutput)) //we are playing
       
   681 			{
       
   682 			if (!iDisableAutoIntent && iDataSource->DataSourceType()==KUidMmfFileSource)
       
   683 					{
       
   684 					CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
   685 					file->ExecuteIntent(ContentAccess::EStop);
       
   686 					}
       
   687 			//  datapath propogates stop to sink & source
       
   688 			iDataPath->Stop();
       
   689 			SetState(EStopped);
       
   690 			}
       
   691 		else
       
   692 			{
       
   693 			//  datapath propogates stop to sink & source
       
   694 			iStoppingPlaying = ETrue;
       
   695 			iDataPath->Stop();			
       
   696 			SetState(EStopped);
       
   697 			iStoppingPlaying = EFalse;
       
   698 			}
       
   699 		}
       
   700 	iIsPaused = EFalse;
       
   701 	iIsPreemptionPause = EFalse;
       
   702 	//complete message as request is complete.
       
   703 	if(State() == EStopped && !IsUnderTest())
       
   704 		{
       
   705 		aMessage.Complete(KErrNone);
       
   706 		}
       
   707 
       
   708 	//[ assert the invariant ]
       
   709 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   710 	}
       
   711 
       
   712 /**
       
   713  *  PositionL
       
   714  * Preconditions:
       
   715  * The Controller is in the state EPrimed
       
   716  * @return TTimeIntervalMicroSeconds
       
   717  *
       
   718  */
       
   719 TTimeIntervalMicroSeconds CMMFAudioController::PositionL() const
       
   720 	{
       
   721 	//[ assert the invariant ]
       
   722 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   723 	// [ precondition that we are playing or primed ]
       
   724 	if( !((State() == EPrimed) || (State() == EPlaying)))
       
   725 			User::Leave(KErrNotReady);
       
   726 
       
   727     TTimeIntervalMicroSeconds position = iDataPath->Position();
       
   728 	
       
   729 	if ((State() == EPlaying) && (iDataSource->DataSourceType()==KUidMmfAudioInput)) 
       
   730                 position = DurationL(); 
       
   731 
       
   732 	//[ assert the invariant ]
       
   733 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   734 
       
   735 	return position;
       
   736 	}
       
   737 
       
   738 /**
       
   739 * SetPositionL
       
   740 *
       
   741 * @param aPosition
       
   742 *
       
   743 */
       
   744 void CMMFAudioController::SetPositionL(const TTimeIntervalMicroSeconds& aPosition)
       
   745 	{
       
   746 	//[ assert the invariant ]
       
   747 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   748 
       
   749 	// [ precondition that we are not already stopped ]
       
   750 	if (iState == EStopped)
       
   751 		User::Leave(KErrNotReady);
       
   752 
       
   753 	//[ precondition that the position is >= 0 && <= Duration ]
       
   754 		{
       
   755 		TTimeIntervalMicroSeconds theDuration(0);
       
   756 		if (iSourceFormat)
       
   757 			{ //if the source is a clip then the duration always refers to the source - even if the sink is a clip
       
   758 			theDuration = iSourceFormat->Duration(iMediaId);
       
   759 			}
       
   760 		else if (iSinkFormat)
       
   761 			{ //duration of recorded clip
       
   762 			theDuration = iSinkFormat->Duration(iMediaId);
       
   763 			}
       
   764 		TTimeIntervalMicroSeconds theStart(0);
       
   765 		if( ( aPosition < theStart) || ( aPosition > theDuration) )
       
   766 			//[ invalid position before start and after end]
       
   767 			User::Leave(KErrArgument);
       
   768 		}
       
   769 
       
   770 	//[ set the position on the data path ]
       
   771 
       
   772 	// if we're already playing, flush all the buffers by calling Stop(),
       
   773 	// PrimeL() and then PlayL() - otherwise we could be waiting a long time.
       
   774 	if (iDataSink->DataSinkType() == KUidMmfAudioOutput && iState == EPlaying)
       
   775 		{
       
   776 		CMMFAudioOutput* audioOutput = static_cast<CMMFAudioOutput*>(iDataSink);
       
   777 		if(!audioOutput->IsResumeSupported())
       
   778 			{
       
   779 		iDataPath->Stop();
       
   780 		SetState(EStopped);
       
   781 		PrimeL();
       
   782 		iDataPath->SetPositionL(aPosition);
       
   783 			iDataPath->RetainRepeatInfo();
       
   784 		PlayL();
       
   785 			}
       
   786 		else
       
   787 			{
       
   788 			iDataPath->Pause();
       
   789 			User::LeaveIfError(audioOutput->SoundDevice().EmptyBuffers());
       
   790 			iDataPath->SetPositionL(aPosition);
       
   791 			iDataPath->RetainRepeatInfo();
       
   792 			// This does a DevSound resume 
       
   793 			iDataPath->PlayL(); 
       
   794 			}
       
   795 		}
       
   796 	else
       
   797 		iDataPath->SetPositionL(aPosition);
       
   798 
       
   799 	//[ assert the invariant ]
       
   800 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   801 
       
   802     // [ post condition not checked ]
       
   803 	//[ we do not compare the set position with get postion
       
   804     //  because the interface to do so is poor ]
       
   805 	}
       
   806 
       
   807 /**
       
   808 *
       
   809 * DurationL
       
   810 *
       
   811 * @returns TTimeIntervalMicroSeconds
       
   812 *
       
   813 */
       
   814 TTimeIntervalMicroSeconds CMMFAudioController::DurationL() const
       
   815 	{
       
   816 	//[ assert the invariant ]
       
   817 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   818 
       
   819 
       
   820 	// [ assert we have a format that supports duration ]
       
   821 	if( !( iSourceFormat || iSinkFormat ) )
       
   822 		User::Leave(KErrNotSupported);
       
   823 
       
   824 	//[ now do the real work of getting the duration ]
       
   825 	// ------------------------------------------------
       
   826 	TTimeIntervalMicroSeconds theDuration(0);
       
   827 	if (iSourceFormat)
       
   828 		{ //if the source is a clip then the duration always refers to the source - even if the sink is a clip
       
   829 		theDuration = iSourceFormat->Duration(iMediaId);
       
   830 		}
       
   831 	else if (iSinkFormat)
       
   832 		{ //duration of recorded clip
       
   833 		theDuration = iSinkFormat->Duration(iMediaId);
       
   834 		}
       
   835 
       
   836 	//[ assert the invariant ]
       
   837 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   838 
       
   839 	return theDuration;
       
   840 	}
       
   841 
       
   842 /**
       
   843 *
       
   844 * GetNumberOfMetaDataEntriesL
       
   845 *
       
   846 * @param "TInt"
       
   847 *
       
   848 */
       
   849 void CMMFAudioController::GetNumberOfMetaDataEntriesL(TInt& aNumberOfEntries )
       
   850 	{
       
   851 
       
   852 	//[ assert the invariant ]
       
   853 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   854 
       
   855 	//[ precondition that we are in the primed state or stopped ]
       
   856 	if( !((State() == EPrimed) || ( State() == EStopped)))
       
   857 		User::Leave(KErrNotReady);
       
   858 
       
   859     // [ precondition there is a sink format ]
       
   860 	if (!iDataSink)
       
   861 		User::Leave(KErrNotSupported);
       
   862 
       
   863 	// [ precondition the sink format is an encode format ]
       
   864 	if ((iDataSink->DataSinkType()!=KUidMmfAudioOutput) &&
       
   865 		(iDataSource->DataSourceType()!= KUidMmfAudioInput) )
       
   866 		User::Leave(KErrNotSupported);
       
   867 
       
   868 	if (iDataSink->DataSinkType()==KUidMmfAudioOutput)
       
   869 		{
       
   870 
       
   871 		//[ precondition the format exists ]
       
   872 		if( !iSourceFormat )
       
   873 			User::Leave(KErrNotSupported);
       
   874 
       
   875 		//[ Get the Number of meta data entries from the sink format ]
       
   876 		iSourceFormat->GetNumberOfMetaDataEntriesL( aNumberOfEntries );
       
   877 		}
       
   878 	else if (iDataSource->DataSourceType()==KUidMmfAudioInput)
       
   879 		{
       
   880 		if( !iSinkFormat )
       
   881 			User::Leave(KErrNotSupported);
       
   882 
       
   883 		iSinkFormat->GetNumberOfMetaDataEntriesL( aNumberOfEntries );
       
   884 		}
       
   885 
       
   886 	//[ assert the invariant ]
       
   887 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   888 
       
   889 	}
       
   890 
       
   891 /**
       
   892 * GetMetaDataEntryL
       
   893 * @param aIndex
       
   894 * @returns "CMMFMetaDataEntry*"
       
   895 */
       
   896 CMMFMetaDataEntry* CMMFAudioController::GetMetaDataEntryL(TInt aIndex )
       
   897 	{
       
   898 		//[ assert the invariant ]
       
   899 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   900 
       
   901 	//[ precondition that we are in the primed state or stopped ]
       
   902 	if( !((State() == EPrimed) || ( State() == EStopped)))
       
   903 		User::Leave(KErrNotReady);
       
   904 
       
   905     // [ precondition there is a sink format ]
       
   906 	if (!iDataSink)
       
   907 		User::Leave(KErrNotSupported);
       
   908 
       
   909 	iDataSink->DataSinkType();
       
   910 	iDataSource->DataSourceType();
       
   911 
       
   912 	// [ precondition the sink or source is either an audio output or input ]
       
   913 	if ((iDataSink->DataSinkType()!= KUidMmfAudioOutput) &&
       
   914 		(iDataSource->DataSourceType()!= KUidMmfAudioInput ))
       
   915 		User::Leave(KErrNotSupported);
       
   916 
       
   917 	//[ Get the meta data entry from the sink format ]
       
   918 	CMMFMetaDataEntry*  theEntry = NULL;
       
   919 
       
   920 	if (iDataSink->DataSinkType()==KUidMmfAudioOutput)
       
   921 		{
       
   922 		//[ precondition the format exists ]
       
   923 		if( !iSourceFormat )
       
   924 			User::Leave(KErrNotSupported);
       
   925 
       
   926 		//[ Get the Number of meta data entries from the sink format ]
       
   927 		theEntry = iSourceFormat->MetaDataEntryL(aIndex);
       
   928 		}
       
   929 	else if (iDataSource->DataSourceType()==KUidMmfAudioInput)
       
   930 		{
       
   931 		//[ precondition the format exits ]
       
   932 		if( !iSinkFormat )
       
   933 			User::Leave(KErrNotSupported);
       
   934 		theEntry = iSinkFormat->MetaDataEntryL(aIndex);
       
   935 		}
       
   936 
       
   937 	//[ assert the post condition that the entry is not null ]
       
   938 	__ASSERT_ALWAYS( theEntry, Panic(EBadInvariant));
       
   939 
       
   940 	//[ assert the invariant ]
       
   941 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   942 
       
   943 	return theEntry;
       
   944 	}
       
   945 
       
   946 /**
       
   947 * RemoveDataSourceL
       
   948 * @param aDataSource
       
   949 *
       
   950 */
       
   951 void CMMFAudioController::RemoveDataSourceL(MDataSource& aDataSource )
       
   952 	{
       
   953 	//[ assert the invariant ]
       
   954 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant) );
       
   955 
       
   956 	//[ precondition is that we have a data source ]
       
   957 	if( !iDataSource )
       
   958 		User::Leave(KErrNotReady);
       
   959 
       
   960 	//[precondition the data source is the data source we have]
       
   961 	if( iDataSource != &aDataSource )
       
   962 		User::Leave(KErrArgument);
       
   963 
       
   964 	//[ the controller is in the stopped state ]
       
   965 	if(State() != EStopped)
       
   966 		User::Leave(KErrNotReady);
       
   967 
       
   968 	//[ remove the data sink from the controller and delete the format]
       
   969      if( iSourceAndSinkAdded )
       
   970 		 {
       
   971          __ASSERT_ALWAYS( iDataPath, Panic( EBadState ));
       
   972 	     //[ Remove references to source and sink ]
       
   973 	     iDataPath->ResetL();
       
   974 		 iSourceAndSinkAdded = EFalse ;
       
   975 		 }
       
   976 
       
   977 	 // [ delete the data sink and format ]
       
   978 	 iDataSource = NULL ;
       
   979 	 delete iSourceFormat;
       
   980 	 iSourceFormat = NULL;
       
   981 
       
   982 	// [ assert postcondition we are stopped ]
       
   983 	__ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
       
   984 
       
   985 	//[ assert postcondition the SourceAndSinkAdded is false ]
       
   986 	__ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
       
   987 
       
   988 	//[ assert postcondition the data sinkformat  is null ]
       
   989 	__ASSERT_ALWAYS( (iSourceFormat == NULL ), Panic( EPostConditionViolation ));
       
   990 
       
   991 	//[ assert postcondition the data sink  is null ]
       
   992 	__ASSERT_ALWAYS( (iDataSource == NULL ), Panic( EPostConditionViolation ));
       
   993 
       
   994 	//[ assert the invariant ]
       
   995 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
   996 
       
   997 	}
       
   998 
       
   999 /**
       
  1000 * RemoveDataSinkL
       
  1001 *
       
  1002 * @param aDataSink
       
  1003 *
       
  1004 */
       
  1005 void CMMFAudioController::RemoveDataSinkL(MDataSink& aDataSink )
       
  1006 	{
       
  1007 	//[ assert the invariant ]
       
  1008 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant) );
       
  1009 
       
  1010 	//[ precondition is that we have a data sink ]
       
  1011 	if( !iDataSink )
       
  1012 		User::Leave(KErrNotSupported);
       
  1013 
       
  1014 	//[precondition the data sink is the data sink we have]
       
  1015 	if( iDataSink != &aDataSink )
       
  1016 		User::Leave(KErrNotSupported);
       
  1017 
       
  1018 	//[ the controller is in the stopped state ]
       
  1019 	if(State() != EStopped)
       
  1020 		User::Leave(KErrNotReady);
       
  1021 
       
  1022 	//[ remove the data sink from the controller and delete the format]
       
  1023      if( iSourceAndSinkAdded )
       
  1024 		 {
       
  1025          __ASSERT_ALWAYS( iDataPath, Panic( EBadState ));
       
  1026          //[ Remove references to source and sink ]
       
  1027 	     iDataPath->ResetL();
       
  1028 		 iSourceAndSinkAdded = EFalse ;
       
  1029 		 }
       
  1030 
       
  1031 	 // [ reset data sink referenece and remove the format ]
       
  1032 	 iDataSink = NULL ;
       
  1033 	 delete iSinkFormat;
       
  1034 	 iSinkFormat = NULL;
       
  1035 
       
  1036 	// [ assert postcondition we are stopped ]
       
  1037 	__ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
       
  1038 
       
  1039 	//[ assert postcondition the SourceAndSinkAdded is false ]
       
  1040 	__ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
       
  1041 
       
  1042 	//[ assert postcondition the data sinkformat  is null ]
       
  1043 	__ASSERT_ALWAYS( (iSinkFormat == NULL ), Panic( EPostConditionViolation ));
       
  1044 
       
  1045 	//[ assert postcondition the data sink  is null ]
       
  1046 	__ASSERT_ALWAYS( (iDataSink == NULL ), Panic( EPostConditionViolation ));
       
  1047 
       
  1048 	//[ assert the invariant ]
       
  1049 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1050 	}
       
  1051 
       
  1052 /**
       
  1053  *  CustomCommand
       
  1054  *  @param aMessage
       
  1055  */
       
  1056 void CMMFAudioController::CustomCommand(TMMFMessage& aMessage)
       
  1057 	{
       
  1058 	//[ assert the invariant ]
       
  1059 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1060 	// [ We do not have any custom commands ]
       
  1061 	aMessage.Complete(KErrNotSupported);
       
  1062 	}
       
  1063 
       
  1064 /**
       
  1065 * NegotiateL
       
  1066 *
       
  1067 */
       
  1068 void CMMFAudioController::NegotiateL()
       
  1069 	{
       
  1070 	//[ assert the invariant ]
       
  1071 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1072 
       
  1073 	//utility function used by custom to negotiate source sink settings after a change
       
  1074 	if ((iSourceFormat)&&(iSinkFormat)) //convert
       
  1075 		{
       
  1076 		iSinkFormat->NegotiateL(*iSourceFormat);
       
  1077 		iSourceFormat->NegotiateSourceL(*iSinkFormat);
       
  1078 		iSinkFormat->NegotiateL(*iSourceFormat);
       
  1079 
       
  1080 		// check for upsampling attempts
       
  1081 		if (iSinkFormat->SampleRate() > iSourceFormat->SampleRate())
       
  1082 			{
       
  1083 			// we don't support upsampling
       
  1084 			User::Leave( KErrNotSupported );
       
  1085 			}
       
  1086 		}
       
  1087 	else if ((iDataSource)&&(iSinkFormat)) //record
       
  1088 		{
       
  1089 		// need two step negotiation for record
       
  1090 		// first try to set the audio input settings to match the required settings for recording
       
  1091 		iDataSource->NegotiateSourceL(*iSinkFormat);
       
  1092 		// now call negotiateL on the sink in order to tell it what the audio input was set to.
       
  1093 		iSinkFormat->NegotiateL(*iDataSource);
       
  1094 		}
       
  1095 	else if ((iSourceFormat)&&(iDataSink)) //play
       
  1096 		{	
       
  1097 		iDataSink->NegotiateL(*iSourceFormat);
       
  1098 		}
       
  1099 	//[ assert the invariant ]
       
  1100 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1101 	}
       
  1102 
       
  1103 /**
       
  1104  *  SetPrioritySettings
       
  1105  *
       
  1106  *	@param aPrioritySettings
       
  1107  */
       
  1108 void CMMFAudioController::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
       
  1109 	{
       
  1110 	//[ assert the invariant ]
       
  1111 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1112 
       
  1113 	//[ update the priority settings of the controller]
       
  1114 	iPrioritySettings = aPrioritySettings;
       
  1115 
       
  1116 	//pass settings on to source and sink
       
  1117 	if (iDataSource)
       
  1118 		{
       
  1119 		iDataSource->SetSourcePrioritySettings(iPrioritySettings);
       
  1120 		}
       
  1121 	if (iDataSink)
       
  1122 		{
       
  1123 		iDataSink->SetSinkPrioritySettings(iPrioritySettings);
       
  1124 		}
       
  1125 
       
  1126     // assert the post condition
       
  1127 	//__ASSERT_ALWAYS( (iPrioritySettings == aPrioritySettings), Panic( ));
       
  1128 	//[ assert the invariant ]
       
  1129 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1130 	}
       
  1131 
       
  1132 /**
       
  1133  *  SendEventToClient
       
  1134  *
       
  1135  *	@param aEvent
       
  1136  */
       
  1137 TInt CMMFAudioController::SendEventToClient(const TMMFEvent& aEvent)
       
  1138 	{
       
  1139 	//[ assert the invariant ]
       
  1140 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1141 
       
  1142 	TMMFEvent controllerEvent;
       
  1143 	//Were going to stop playing, force event type to be the correct type
       
  1144 	controllerEvent.iEventType = KMMFEventCategoryPlaybackComplete;
       
  1145 	controllerEvent.iErrorCode = aEvent.iErrorCode;
       
  1146 
       
  1147 
       
  1148 
       
  1149 	//If we receive KErrNone from the DataPath, it indicates that it has
       
  1150 	//successfully completed playing/converting/recording.
       
  1151 	if ((aEvent.iEventType == KMMFEventCategoryPlaybackComplete) &&
       
  1152 		(aEvent.iErrorCode == KErrNone))
       
  1153 		{
       
  1154 		if(iStoppingRecording)
       
  1155 			{
       
  1156 			iStoppingRecording = EFalse;
       
  1157 			iDataPath->Stop();
       
  1158 			SetState( EStopped );
       
  1159 
       
  1160 			//complete the clients stop request
       
  1161 			iStoppingMessage->Complete(KErrNone);
       
  1162 			delete iStoppingMessage; iStoppingMessage=NULL;
       
  1163 
       
  1164 			//we don't want to send an event to the client
       
  1165 			return KErrNone;
       
  1166 			}
       
  1167 		else
       
  1168 			{//datapath has reached end of file so set internal state to primed
       
  1169 			SetState( EPrimed );
       
  1170 			}
       
  1171 		}
       
  1172 
       
  1173     //If the client has not registered for the ARN, 
       
  1174     //and a pre-emption happens we need to goto the Pause state
       
  1175     //instead of the Stop state. this should happen only in the case of playback. 
       
  1176 	//In case of recoding we goto the stop state.
       
  1177 	else if(!iRegisterARN && 
       
  1178         (aEvent.iErrorCode == KErrAccessDenied || aEvent.iErrorCode == KErrInUse ||aEvent.iErrorCode == KErrDied)
       
  1179         &&  (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  1180         {
       
  1181         //setting iIsPreemptionPause to true so that PauseL can make differentiate it from normal pause.
       
  1182         iIsPreemptionPause = ETrue;
       
  1183 		TRAPD(err,PauseL());
       
  1184 		if(err != KErrNone)
       
  1185 		    {
       
  1186 			iDataPath->Stop();
       
  1187 			SetState( EStopped );
       
  1188 			iIsPreemptionPause = EFalse;
       
  1189 		    }
       
  1190         }
       
  1191 	else
       
  1192 		{
       
  1193 		if ( State()!= EStopped)
       
  1194 			{
       
  1195 			//we don't want to send an event to the client
       
  1196 			// if we are already in the process of Stopping
       
  1197 			if(iStoppingPlaying)
       
  1198 				{
       
  1199 				return KErrNone;
       
  1200 				}
       
  1201 			
       
  1202 			//datapath propogates stop to sink & source	
       
  1203 			iDataPath->Stop();
       
  1204 			SetState( EStopped );
       
  1205 
       
  1206 			if(iStoppingRecording)
       
  1207 				{// an error has occurred while we were waiting for recording to stop,
       
  1208 				 //must complete clients request
       
  1209 				iStoppingRecording = EFalse;
       
  1210 				iStoppingMessage->Complete(aEvent.iErrorCode);
       
  1211 				delete iStoppingMessage; iStoppingMessage=NULL;
       
  1212 				}
       
  1213 			}
       
  1214 		}
       
  1215 		
       
  1216 	if(!iIsPreemptionPause)
       
  1217 		{
       
  1218 		//should call ExecuteIntent to tell the DRM agent that playback has stopped 	
       
  1219 		if (aEvent.iEventType == KMMFEventCategoryPlaybackComplete) 
       
  1220 			{
       
  1221 			if ((iDataSink->DataSinkType() == KUidMmfAudioOutput)) 
       
  1222 				{		
       
  1223 				if (!iDisableAutoIntent && iDataSource->DataSourceType()==KUidMmfFileSource)
       
  1224 					{
       
  1225 					CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
  1226 					file->ExecuteIntent(ContentAccess::EStop);
       
  1227 					}
       
  1228 				}
       
  1229 			}
       
  1230 		}
       
  1231 
       
  1232 
       
  1233 	//now send event to client...
       
  1234 	TInt result = KErrNone;
       
  1235 	if(aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable)
       
  1236 		{
       
  1237 		result = DoSendEventToClient(aEvent);
       
  1238 		}
       
  1239 	else
       
  1240 		{
       
  1241 		result = DoSendEventToClient(controllerEvent);
       
  1242 		}
       
  1243 
       
  1244 	//[ assert the invariant ]
       
  1245 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1246 
       
  1247 	return result;
       
  1248 	}
       
  1249 
       
  1250 
       
  1251 /**
       
  1252 * MapdSetVolumeL
       
  1253 *
       
  1254 *  @param aVolume
       
  1255 *
       
  1256 */
       
  1257 void CMMFAudioController::MapdSetVolumeL(TInt aVolume)
       
  1258 	{
       
  1259 	//[ assert the invariant ]
       
  1260 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1261 
       
  1262 	// [  precondition is true for state
       
  1263 	//    we can set the volume in any state ]
       
  1264 
       
  1265 	//[ precondition we have a data sink ]
       
  1266 	if (!iDataSink)
       
  1267 		User::Leave(KErrNotReady);
       
  1268 
       
  1269     // [ precondition that the data sink is an audio output ]
       
  1270 	// Make sure that iDataSink is an Audio Output
       
  1271 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1272 				User::Leave(KErrNotSupported);
       
  1273 
       
  1274 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1275 
       
  1276 	// [ assert the precondition that aVolume is in range ]
       
  1277 	TInt maxVolume = audioOutput->SoundDevice().MaxVolume();
       
  1278 	if( ( aVolume < 0 ) || ( aVolume > maxVolume ))
       
  1279 			User::Leave(KErrArgument);
       
  1280 
       
  1281 	//[ set the volume on the device ]
       
  1282 	audioOutput->SoundDevice().SetVolume(aVolume);
       
  1283 
       
  1284 	//[ assert the post condition volume is equal to a volume]
       
  1285 	TInt soundVolume = 0;
       
  1286 	soundVolume = audioOutput->SoundDevice().Volume();
       
  1287 
       
  1288     __ASSERT_ALWAYS( ( soundVolume == aVolume), Panic(EPostConditionViolation));
       
  1289 
       
  1290 	//[ assert the invariant ]
       
  1291 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1292 	}
       
  1293 
       
  1294 /**
       
  1295 *
       
  1296 * MapdGetMaxVolumeL
       
  1297 *
       
  1298 * @param aMaxVolume
       
  1299 *
       
  1300 */
       
  1301 void CMMFAudioController::MapdGetMaxVolumeL(TInt& aMaxVolume)
       
  1302 	{
       
  1303 	// [ assert the invariant ]
       
  1304 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1305 
       
  1306 	//[ we can get max volume in any state ]
       
  1307 
       
  1308 	// [ precondition we must have a data sink ]
       
  1309 	if (!iDataSink)
       
  1310 		User::Leave(KErrNotReady);
       
  1311 
       
  1312 	//[ precondition the sink must be an audio output]
       
  1313 	// Make sure that iDataSink is an Audio Output
       
  1314 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1315 			User::Leave(KErrNotSupported);
       
  1316 
       
  1317 	//[ get the volume from the device ]
       
  1318 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1319 	aMaxVolume = audioOutput->SoundDevice().MaxVolume();
       
  1320 
       
  1321 	//[ assert the invariant ]
       
  1322 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1323 
       
  1324 	}
       
  1325 
       
  1326 
       
  1327 /**
       
  1328 *
       
  1329 * MapdGetVolumeL
       
  1330 *
       
  1331 * @param aVolume
       
  1332 *
       
  1333 */
       
  1334 void CMMFAudioController::MapdGetVolumeL(TInt& aVolume)
       
  1335 	{
       
  1336 	// [ assert the invariant ]
       
  1337 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1338 
       
  1339 	//[  precondition that we have a data sink ]
       
  1340 	if (!iDataSink)
       
  1341 		User::Leave(KErrNotReady);
       
  1342 
       
  1343 	//[ precondition iDataSink is an Audio Output ]
       
  1344 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1345 		User::Leave(KErrNotSupported);
       
  1346 
       
  1347 	// [ get the volume ]
       
  1348 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1349 	aVolume = audioOutput->SoundDevice().Volume();
       
  1350 
       
  1351 	// [ assert precondition that the volume is in range
       
  1352 	//     0.. aMaxVolume ]
       
  1353 	TInt aMaxVolume = audioOutput->SoundDevice().MaxVolume();
       
  1354 	__ASSERT_ALWAYS( (aVolume <= aMaxVolume), Panic(EBadState));
       
  1355 	__ASSERT_ALWAYS( (aVolume >= 0), Panic(EBadState));
       
  1356 
       
  1357 	// [ assert the invariant ]
       
  1358 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1359 
       
  1360 	}
       
  1361 
       
  1362 /**
       
  1363 *
       
  1364 * MapdSetVolumeRampL
       
  1365 *
       
  1366 * @param aRampDuration
       
  1367 *
       
  1368 */
       
  1369 void CMMFAudioController::MapdSetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration)
       
  1370 	{
       
  1371      // [ assert the invariant ]
       
  1372 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1373 
       
  1374 	//[ precondition that we have a data sink ]
       
  1375 	if (!iDataSink)
       
  1376 		User::Leave(KErrNotReady);
       
  1377 
       
  1378 	// [ precondition iDataSink is an Audio Output ]
       
  1379 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1380 		User::Leave(KErrNotSupported);
       
  1381 
       
  1382 	//[ set the volume ramp ]
       
  1383 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1384 	audioOutput->SoundDevice().SetVolumeRamp(aRampDuration);
       
  1385 
       
  1386 	//[ assert the invariant ]
       
  1387 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1388 
       
  1389 	}
       
  1390 
       
  1391 
       
  1392 /**
       
  1393 *
       
  1394 * MapdSetBalanceL
       
  1395 *
       
  1396 * @param aBalance
       
  1397 *
       
  1398 */
       
  1399 void CMMFAudioController::MapdSetBalanceL(TInt aBalance)
       
  1400 	{
       
  1401 	//[ assert the invariant ]
       
  1402 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  1403 
       
  1404 	// [ precondition is that we have a data sink ]
       
  1405 	if (!iDataSink)
       
  1406 		User::Leave(KErrNotReady);
       
  1407 
       
  1408 	// [ precondition is that the data sink is an audio output]
       
  1409 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1410 		User::Leave(KErrNotSupported);
       
  1411 
       
  1412 	//[ get the audio output ]
       
  1413 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1414 
       
  1415 	// [ separate out left and right balance ]
       
  1416 	TInt left  = 0;
       
  1417 	TInt right = 0;
       
  1418 	CalculateLeftRightBalance( left, right, aBalance );
       
  1419 
       
  1420 	//[ set the balance ]
       
  1421 	audioOutput->SoundDevice().SetPlayBalanceL(left, right);
       
  1422 
       
  1423 	// [assert the post condition that the balance is set correctly]
       
  1424 	TInt rightBalance = 0;
       
  1425 	TInt leftBalance  = 0;
       
  1426 	audioOutput->SoundDevice().GetPlayBalanceL(leftBalance, rightBalance);
       
  1427 
       
  1428 	//[ assert post condition holds]
       
  1429 	TBool postCondition = (( rightBalance == right) && ( leftBalance == left));
       
  1430 	__ASSERT_ALWAYS( postCondition, Panic( EPostConditionViolation ) );
       
  1431 
       
  1432 	//[ assert the invariant ]
       
  1433 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  1434 	}
       
  1435 
       
  1436 /**
       
  1437 * CalculateLeftRightBalance
       
  1438 * @internalTechnology
       
  1439 * @param aLeft
       
  1440 * @param aRight
       
  1441 * @param aBalance
       
  1442 * Preconditions:
       
  1443 * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight)
       
  1444 * y = m x + c
       
  1445 * aLeft = m ( aBalance ) + c
       
  1446 * when aBalance = KMMFBalanceMaxLeft   aLeft = 100
       
  1447 * when aBalance = KMMFBalanceMaxRight  aLeft = 0
       
  1448 * 100 = m( KMMFBalanceMaxLeft ) + c
       
  1449 * 0   = m( KMMFBalanceMaxRight ) + c
       
  1450 * c = -(KMMFBalanceMaxRight) m
       
  1451 * 100 = m(KMMFBalanceMaxLeft ) - m(KMMFBalanceMaxRight)
       
  1452 * m = 100/(KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
       
  1453 * c = -(KMMFBalanceMaxRight) * 100 /(KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
       
  1454 * aLeft = ( aBalance - KMMFBalanceMaxRight ) * 100 /( KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
       
  1455 */
       
  1456 void CMMFAudioController::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
       
  1457 	{
       
  1458 	// Check the balance is within limits & modify to min or max values if necessary
       
  1459 	if (aBalance < KMMFBalanceMaxLeft)
       
  1460 		aBalance = KMMFBalanceMaxLeft;
       
  1461 	if (aBalance > KMMFBalanceMaxRight)
       
  1462 		aBalance = KMMFBalanceMaxRight;
       
  1463 
       
  1464 	// [ assert precondition that aBalance is within limits ]
       
  1465     __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
       
  1466 
       
  1467 	//[ Now separate percentage balances out from aBalance ]
       
  1468 	 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
       
  1469      aRight = 100 - aLeft;
       
  1470 
       
  1471 	 //[ assert post condition that left and right are within range ]
       
  1472 	 __ASSERT_ALWAYS( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPostConditionViolation));
       
  1473 	 __ASSERT_ALWAYS( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPostConditionViolation));
       
  1474 	}
       
  1475 
       
  1476 
       
  1477 /**
       
  1478 * MapdGetBalanceL
       
  1479 * @param aBalance
       
  1480 *
       
  1481 */
       
  1482 void CMMFAudioController::MapdGetBalanceL(TInt& aBalance)
       
  1483 	{
       
  1484 	//[ assert the invariant ]
       
  1485 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1486 
       
  1487 	//[ precondition that we have a sink]
       
  1488 	if (!iDataSink)
       
  1489 		User::Leave(KErrNotReady);
       
  1490 
       
  1491 	// [ iDataSink is an Audio Output ]
       
  1492 	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1493 		User::Leave(KErrNotSupported);
       
  1494 
       
  1495 	// [ get the play balance ]
       
  1496 	MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  1497 	TInt left = 50; // arbitrary values
       
  1498 	TInt right = 50;
       
  1499 	audioOutput->SoundDevice().GetPlayBalanceL(left, right);
       
  1500     CalculateBalance( aBalance, left, right );
       
  1501 
       
  1502 	//[ assert the invariant ]
       
  1503 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1504 	}
       
  1505 
       
  1506 /**
       
  1507 * CalculateBalance
       
  1508 * @param aBalance
       
  1509 * @param aLeft
       
  1510 * @param aRight
       
  1511 *
       
  1512 * follows a simple straight line transformation
       
  1513 * y = m x + c
       
  1514 * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100
       
  1515 * c = KMMFBalanceMaxRight
       
  1516 * by substitution
       
  1517 * when aLeft = 0
       
  1518 *   KMMFBalanceMaxRight = m * 0 + c
       
  1519 *   c = KMMFBalanceMaxRight
       
  1520 * when aLeft = 100
       
  1521 * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight
       
  1522 * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100
       
  1523 */
       
  1524 void CMMFAudioController::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
       
  1525 	{
       
  1526 	//[ assert pre conditions ]
       
  1527 	__ASSERT_ALWAYS( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EBadArgument) );
       
  1528 	__ASSERT_ALWAYS( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EBadArgument) );
       
  1529 
       
  1530 	if ((aLeft > 0) && (aRight > 0))
       
  1531 		{
       
  1532 		__ASSERT_ALWAYS( (( aLeft + aRight ) == 100 ), Panic( EBadArgument ));
       
  1533 		aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
       
  1534 		}
       
  1535 	else if ((aLeft == 0) && (aRight == 0))
       
  1536 		{
       
  1537 		aBalance = 0;
       
  1538 		}
       
  1539 	else if ((aLeft == 0) && (aRight > 0))
       
  1540 		{
       
  1541 		aBalance = 100;
       
  1542 		}
       
  1543 	else if ((aLeft > 0) && (aRight == 0))
       
  1544 		{
       
  1545 		aBalance = -100;
       
  1546 		}
       
  1547 
       
  1548     //[ assert post condition that aBalance is within limits ]
       
  1549 	__ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
       
  1550 
       
  1551 	}
       
  1552 
       
  1553 /**
       
  1554 * MardSetGainL
       
  1555 * @param aGain
       
  1556 *
       
  1557 */
       
  1558 void CMMFAudioController::MardSetGainL(TInt aGain)
       
  1559 	{
       
  1560 	// [ assert the invariant ]
       
  1561 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1562 
       
  1563 	//[ precondition we are in the state stopped ]
       
  1564 	if(State() != EStopped)
       
  1565 		User::Leave(KErrNotReady);
       
  1566 
       
  1567 	// [ assert the precondition that we have a data sink ]
       
  1568 	if (!iDataSource)
       
  1569 		User::Leave(KErrNotSupported);
       
  1570 
       
  1571 	//[ assert the precondition that the data sink is an audio input ]
       
  1572 	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
       
  1573 		User::Leave(KErrNotReady);
       
  1574 
       
  1575 	// Set gain of sound device
       
  1576 	MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  1577 	audioInput->SoundDevice().SetGain(aGain);
       
  1578 
       
  1579 	//[ assert the invariant ]
       
  1580 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1581 
       
  1582 	}
       
  1583 
       
  1584 /**
       
  1585 * MardGetMaxGainL
       
  1586 * @param aMaxGain
       
  1587 *
       
  1588 */
       
  1589 void CMMFAudioController::MardGetMaxGainL(TInt& aMaxGain)
       
  1590 	{
       
  1591 	// [ assert the invariant ]
       
  1592 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1593 
       
  1594 	// [ assert the precondition that we have a source ]
       
  1595 	if (!iDataSource)
       
  1596 		User::Leave(KErrNotReady);
       
  1597 
       
  1598 	//[ assert the precondition that iDataSink is an Audio Input]
       
  1599 	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
       
  1600 		User::Leave(KErrNotSupported);
       
  1601 
       
  1602 	MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  1603 	aMaxGain = audioInput->SoundDevice().MaxGain();
       
  1604 
       
  1605 	//[ assert the invariant ]
       
  1606 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1607 
       
  1608 	}
       
  1609 
       
  1610 /**
       
  1611 * MardGetGainL
       
  1612 * @param aGain
       
  1613 *
       
  1614 */
       
  1615 void CMMFAudioController::MardGetGainL(TInt& aGain)
       
  1616 	{
       
  1617 	//[ assert the invariant ]
       
  1618 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1619 
       
  1620 	// [ assert the precondition that we have a sink ]
       
  1621 	if (!iDataSource)
       
  1622 		User::Leave(KErrNotReady);
       
  1623 
       
  1624 	// [ assert the precondition that we have an audio input sink]
       
  1625 	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
       
  1626 			User::Leave(KErrNotSupported);
       
  1627 
       
  1628 	MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  1629 	aGain = audioInput->SoundDevice().Gain();
       
  1630 
       
  1631 	//[ assert the invariant ]
       
  1632 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1633 	}
       
  1634 
       
  1635 
       
  1636 /**
       
  1637  *
       
  1638  * MardSetBalanceL
       
  1639  *   @param aBalance
       
  1640  */
       
  1641 void CMMFAudioController::MardSetBalanceL(TInt aBalance)
       
  1642 	{
       
  1643 	// [ assert the invaraiant ]
       
  1644 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1645 
       
  1646 	// [ precondition is that we have a data sink ]
       
  1647 	if (!iDataSink)
       
  1648 		User::Leave(KErrNotReady);
       
  1649 
       
  1650 	// [ precondition is that the balance is in range ]
       
  1651 	// Make sure aBalance is in the range -100 <-> 100
       
  1652 	if (aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight)
       
  1653 		User::Leave(KErrArgument);
       
  1654 
       
  1655 	// [ precondition is that the data sink is an audio output]
       
  1656 	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
       
  1657 		User::Leave(KErrNotSupported);
       
  1658 
       
  1659 
       
  1660 	//[ get the audio output ]
       
  1661 	MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  1662 
       
  1663 	// [ separate out left and right balance ]
       
  1664 	TInt left  = 0;
       
  1665 	TInt right = 0;
       
  1666 	CalculateLeftRightBalance( left, right, aBalance );
       
  1667 
       
  1668 	//[ set the balance ]
       
  1669 	audioInput->SoundDevice().SetRecordBalanceL(left, right);
       
  1670 
       
  1671 	// [assert the post condition that the balance is set correctly]
       
  1672 	TInt rightBalance = 0;
       
  1673 	TInt leftBalance  = 0;
       
  1674 	audioInput->SoundDevice().GetRecordBalanceL(leftBalance, rightBalance);
       
  1675 
       
  1676 	//[ assert post condition holds]
       
  1677 	TBool postCondition = (( rightBalance == right) && ( leftBalance == left));
       
  1678 	__ASSERT_ALWAYS( postCondition, Panic( EPostConditionViolation ) );
       
  1679 
       
  1680 	//[ assert the invariant ]
       
  1681 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  1682 
       
  1683 	}
       
  1684 
       
  1685 /**
       
  1686 *
       
  1687 * MardGetBalanceL
       
  1688 * @param aBalance
       
  1689 *
       
  1690 */
       
  1691 void CMMFAudioController::MardGetBalanceL(TInt& aBalance)
       
  1692 	{
       
  1693 	//[ assert the invariant ]
       
  1694 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1695 
       
  1696 	//[ precondition that we have a sink]
       
  1697 	if (!iDataSink)
       
  1698 		User::Leave(KErrNotReady);
       
  1699 
       
  1700 	// [ iDataSink is an Audio Output ]
       
  1701 	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
       
  1702 		User::Leave(KErrNotSupported);
       
  1703 
       
  1704 	// [ get the play balance ]
       
  1705 	MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  1706 	TInt left = 50; // arbitrary values
       
  1707 	TInt right = 50;
       
  1708 	audioInput->SoundDevice().GetRecordBalanceL(left, right);
       
  1709     CalculateBalance( aBalance, left, right );
       
  1710 
       
  1711 	//[ assert the invariant ]
       
  1712 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1713 
       
  1714 	}
       
  1715 
       
  1716 /**
       
  1717 * MapcSetPlaybackWindowL
       
  1718 * @param aStart
       
  1719 * @param aEnd
       
  1720 *
       
  1721 */
       
  1722 void CMMFAudioController::MapcSetPlaybackWindowL(const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd)
       
  1723 	{
       
  1724 	iDataPath->SetPlayWindowL(aStart, aEnd);
       
  1725 	}
       
  1726 
       
  1727 /**
       
  1728 * MapcDeletePlaybackWindowL
       
  1729 */
       
  1730 void CMMFAudioController::MapcDeletePlaybackWindowL()
       
  1731 	{
       
  1732 	iDataPath->ClearPlayWindowL();
       
  1733 	}
       
  1734 
       
  1735 
       
  1736 /**
       
  1737 * MapcSetRepeatsL
       
  1738 * @param aRepeatNumberOfTimes
       
  1739 * @param aTrailingSilence
       
  1740 *
       
  1741 */
       
  1742 
       
  1743 TInt CMMFAudioController::MapcSetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
       
  1744 	{
       
  1745 	TInt err = KErrNone;
       
  1746 #ifdef _DEBUG
       
  1747 	RDebug::Print(_L("CMMFAudioController::MapcSetRepeats Enter "));
       
  1748 #endif
       
  1749 	if (!iDataSink)
       
  1750 		{
       
  1751 		err = KErrNotReady;
       
  1752 		}
       
  1753 	else if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
       
  1754 		{
       
  1755 		err = KErrNotSupported;
       
  1756 		}
       
  1757 	else
       
  1758 		{
       
  1759 		MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
  1760 		if(audioOutput->SoundDevice().QueryIgnoresUnderflow())
       
  1761 			{
       
  1762 #ifdef _DEBUG
       
  1763 	RDebug::Print(_L("CMMFAudioController::MapcSetRepeats RepeatCount [%d] TrailingSilence [%d]"),aRepeatNumberOfTimes, aTrailingSilence.Int64());
       
  1764 #endif
       
  1765 			iDataPath->SetRepeats(aRepeatNumberOfTimes,aTrailingSilence);
       
  1766 			iDataPath->SetDrmProperties(iDataSource, &iDisableAutoIntent);
       
  1767 			}
       
  1768 		else
       
  1769 			{
       
  1770 			err = KErrNotSupported;
       
  1771 			}
       
  1772 		}
       
  1773 	return err;
       
  1774 	}
       
  1775 
       
  1776 
       
  1777 /**
       
  1778 * MapcGetLoadingProgressL
       
  1779 */
       
  1780 void CMMFAudioController::MapcGetLoadingProgressL(TInt& /*aPercentageComplete*/)
       
  1781 	{
       
  1782 	User::Leave(KErrNotSupported);
       
  1783 	}
       
  1784 
       
  1785 
       
  1786 /**
       
  1787 * MarcGetRecordTimeAvailableL
       
  1788 * @param aTime
       
  1789 *
       
  1790 */
       
  1791 void CMMFAudioController::MarcGetRecordTimeAvailableL(TTimeIntervalMicroSeconds& aTime)
       
  1792 	{
       
  1793 	//[ assert the invariant ]
       
  1794 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1795 
       
  1796 	//[ assert the precondition ( in a friendly way for this api
       
  1797 	// that we minimally have a data sink ]
       
  1798 	if( !iDataSink )
       
  1799 		User::Leave( KErrNotReady );
       
  1800 
       
  1801 	// Use the FormatEncode to get the bytes per second and the sink (clip) to get the bytes available
       
  1802 	// return the calculated value.
       
  1803 	if	((iDataSink->DataSinkType() != KUidMmfFileSink) && (iDataSink->DataSinkType() != KUidMmfDescriptorSink))
       
  1804 		User::Leave(KErrNotSupported) ;
       
  1805 
       
  1806 	// [ max file size ]
       
  1807 	//[ pre condition is that we have a sink ]
       
  1808 
       
  1809 	// In order to get the record time available we need to take into consideration
       
  1810 	// that there may be a max file size ]
       
  1811 	TInt64 bytesFree       = STATIC_CAST(CMMFClip*, iDataSink)->BytesFree() ;
       
  1812 	TInt64 bytesPerSecond  = TInt64(0);
       
  1813 	//[ set default time available ]
       
  1814 	       aTime           = TTimeIntervalMicroSeconds( 0 ) ; // just return zero
       
  1815 
       
  1816 	if( iSinkFormat )
       
  1817 		{
       
  1818 		TInt maxFileSize = STATIC_CAST(CMMFFormatEncode*, iSinkFormat)->MaximumClipSize();
       
  1819 		//[ if maxFileSize > 0 we need to limit the bytes free to this value - size ]
       
  1820 		if( maxFileSize > 0 )
       
  1821 			{
       
  1822 			// [ strangely the size of data written is a TInt ]
       
  1823 			TInt fileSize = STATIC_CAST(CMMFClip*, iDataSink)->Size();
       
  1824 			bytesFree = maxFileSize - fileSize;
       
  1825 			// [ note it can occur that the fileSize id greater than the MaxFileSize
       
  1826 			//  due to someone setting the max file size on an existing file ]
       
  1827 			if( bytesFree < 0 ) bytesFree = 0;
       
  1828 			__ASSERT_DEBUG( ( bytesFree <= maxFileSize), Panic(	EBadInvariant) );
       
  1829 			}
       
  1830 		bytesPerSecond = STATIC_CAST(CMMFFormatEncode*, iSinkFormat)->BytesPerSecond() ;
       
  1831 		}
       
  1832 
       
  1833 	//[ now lets perform the calculation of time available ]
       
  1834 	if ( bytesPerSecond != TInt64(0) )
       
  1835 		{
       
  1836 		aTime = TTimeIntervalMicroSeconds( bytesFree * KOneSecondInMicroSeconds / bytesPerSecond ) ;
       
  1837 		}
       
  1838 
       
  1839 	//[ assert the invariant ]
       
  1840 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1841 	}
       
  1842 
       
  1843 /**
       
  1844 * MarcSetMaxDurationL
       
  1845 * @param aMaxDuration
       
  1846 */
       
  1847 void CMMFAudioController::MarcSetMaxDurationL(const TTimeIntervalMicroSeconds& )
       
  1848 	{
       
  1849 	//[ this method is deprecated and no longer supported ]
       
  1850 	User::Leave(KErrNotSupported);
       
  1851 	}
       
  1852 
       
  1853 /**
       
  1854 * MarcSetMaxFileSizeL
       
  1855 * @param aFileSize
       
  1856 * @precondition
       
  1857 * The argument aFileSize must be greater than -1
       
  1858 * zero is used as a sentinel value which means that the file
       
  1859 * can grow without limit
       
  1860 */
       
  1861 void CMMFAudioController::MarcSetMaxFileSizeL(TInt aFileSize )
       
  1862 	{
       
  1863 	//[ assert the invariant ]
       
  1864 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1865 
       
  1866 	//[ assert the state is not playing since this opens open
       
  1867 	// nefarious posibilities
       
  1868 	if(State() == EPlaying )
       
  1869 		User::Leave( KErrNotReady );
       
  1870 
       
  1871 	//[ assert we have a sink format ]
       
  1872 	if( !iSinkFormat )
       
  1873 		User::Leave( KErrNotReady );
       
  1874 
       
  1875 	//[ assert file size > -1, as a basic sanity filter
       
  1876 	// 0 is the sentinel value which allows a file to grow
       
  1877 	// as needed ]
       
  1878 	if( aFileSize < 0 )
       
  1879 		User::Leave( KErrArgument );
       
  1880 
       
  1881     //[ pre condition is that we have a sink ]
       
  1882     STATIC_CAST(CMMFFormatEncode*, iSinkFormat)->SetMaximumClipSizeL( aFileSize );
       
  1883 
       
  1884 	// [ assert the post condition ]
       
  1885 	// [since we have no means of querying the value
       
  1886 	// we have to assume all went well for now or we left]
       
  1887 
       
  1888 	//[ assert the invariant ]
       
  1889 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1890 	}
       
  1891 
       
  1892 /**
       
  1893 * MarcCropL
       
  1894 * @param aToEnd
       
  1895 */
       
  1896 void CMMFAudioController::MarcCropL(TBool aToEnd)
       
  1897 	{
       
  1898 	//[ assert the invariant ]
       
  1899 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1900 
       
  1901 	//[ precondition there is a sink format]
       
  1902 	if (!iSinkFormat)
       
  1903 		User::Leave(KErrNotSupported);
       
  1904 
       
  1905 	iSinkFormat->CropL( PositionL(), aToEnd );
       
  1906 
       
  1907 	//[ assert the invariant ]
       
  1908 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1909 	}
       
  1910 
       
  1911 /**
       
  1912 * MarcAddMetaDataEntryL
       
  1913 * @param aNewEntry
       
  1914 */
       
  1915 void CMMFAudioController::MarcAddMetaDataEntryL(const CMMFMetaDataEntry& aNewEntry )
       
  1916 	{
       
  1917 	//[ assert the invariant ]
       
  1918 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1919 
       
  1920 	//[ precondition the format exists ]
       
  1921 	if( !iSinkFormat )
       
  1922 		User::Leave(KErrNotSupported);
       
  1923 
       
  1924 	//[ Add the meta data entry ]
       
  1925 	iSinkFormat->AddMetaDataEntryL( aNewEntry );
       
  1926 
       
  1927 	//[ assert the invariant ]
       
  1928 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1929 
       
  1930 	}
       
  1931 
       
  1932 /**
       
  1933 * MarcRemoveMetaDataEntryL
       
  1934 * @param aIndex
       
  1935 */
       
  1936 void CMMFAudioController::MarcRemoveMetaDataEntryL(TInt aIndex)
       
  1937 	{
       
  1938 	//[ assert the invariant ]
       
  1939 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1940 
       
  1941 	//[ precondition that we are in the primed state ]
       
  1942 	if( State() != EPrimed)
       
  1943 		User::Leave(KErrNotReady);
       
  1944 
       
  1945     //[ precondition the format exists ]
       
  1946 	if( !iSinkFormat )
       
  1947 		User::Leave(KErrNotSupported);
       
  1948 
       
  1949 	//[ remove the meta data entry ]
       
  1950 	iSinkFormat->RemoveMetaDataEntry( aIndex );
       
  1951 
       
  1952 	//[ assert the invariant ]
       
  1953 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1954 
       
  1955 	}
       
  1956 
       
  1957 /**
       
  1958 * MarcReplaceMetaDataEntryL
       
  1959 * @param aIndex
       
  1960 * @param aNewEntry
       
  1961 */
       
  1962 void CMMFAudioController::MarcReplaceMetaDataEntryL(TInt aIndex, const CMMFMetaDataEntry& aNewEntry)
       
  1963 	{
       
  1964 	//[ assert the invariant ]
       
  1965 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1966 
       
  1967 	//[ precondition that we are in the primed state ]
       
  1968 	if( State() != EPrimed)
       
  1969 		User::Leave(KErrNotReady);
       
  1970 
       
  1971    	//[ precondition the format exists ]
       
  1972 	if( !iSinkFormat )
       
  1973 		User::Leave(KErrNotSupported);
       
  1974 
       
  1975 	//[ replace meta data entry ]
       
  1976 	iSinkFormat->ReplaceMetaDataEntryL( aIndex, aNewEntry );
       
  1977 
       
  1978 	//[ assert the invariant ]
       
  1979 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  1980 
       
  1981 	}
       
  1982 
       
  1983 /**
       
  1984 * MacSetSourceSampleRateL
       
  1985 * @param aSampleRate
       
  1986 */
       
  1987 void CMMFAudioController::MacSetSourceSampleRateL(TUint aSampleRate)
       
  1988 	{
       
  1989 	// [ assert the invariant ]
       
  1990 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  1991 
       
  1992 	// [ assert the precondition we are stopped ]
       
  1993 	if( State() != EStopped )
       
  1994 		User::Leave(KErrNotReady);
       
  1995 
       
  1996 
       
  1997 	if (iSourceFormat)
       
  1998 		{//only applicable to formats
       
  1999 		// don't throw an error if the clip already exists with a different sample rate
       
  2000 		TInt error = iSourceFormat->SetSampleRate(aSampleRate);
       
  2001 		if (error != KErrNone && error != KErrAlreadyExists)
       
  2002 			User::Leave(error);
       
  2003 		}
       
  2004 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2005 		{
       
  2006 		// cast iDataSource to audio input and set sample rate
       
  2007 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2008 
       
  2009 		//note that it is safe to call SoundDevice()
       
  2010 		//as the controller logs onto the iDataSource when it is added
       
  2011 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Config();
       
  2012 
       
  2013 		ConvertFromSampleRateToDevSoundCapsL(aSampleRate, devSoundConfig);
       
  2014 		ai->SoundDevice().SetConfigL(devSoundConfig);
       
  2015 		//ReNegotiateL();
       
  2016 		}
       
  2017 	else
       
  2018 		User::Leave(KErrNotSupported);
       
  2019 
       
  2020 	// [assert the post condition ]
       
  2021 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2022 
       
  2023 	}
       
  2024 
       
  2025 /**
       
  2026 * MacSetSourceNumChannelsL
       
  2027 * @param aNumChannels
       
  2028 */
       
  2029 void CMMFAudioController::MacSetSourceNumChannelsL(TUint aNumChannels)
       
  2030 	{
       
  2031 	// [ assert the invariant ]
       
  2032 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2033 
       
  2034 	// [assert the precondition that we are stopped ]
       
  2035 	if( State() != EStopped )
       
  2036 		User::Leave(KErrNotReady);
       
  2037 
       
  2038 	if (iSourceFormat)
       
  2039 		{//only applicable to formats
       
  2040 		// don't throw an error if the clip already exists with a different number of channels
       
  2041 		TInt error = iSourceFormat->SetNumChannels(aNumChannels);
       
  2042 		if (error != KErrNone && error != KErrAlreadyExists)
       
  2043 			User::Leave(error);
       
  2044 		}
       
  2045 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2046 		{
       
  2047 		// cast iDataSource to audio input and set num channels
       
  2048 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2049 
       
  2050 		//note that it is safe to call SoundDevice()
       
  2051 		//as the controller logs onto the iDataSource when it is added
       
  2052 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Config();
       
  2053 
       
  2054 		ConvertFromNumChannelsToDevSoundCapsL(aNumChannels, devSoundConfig);
       
  2055 		ai->SoundDevice().SetConfigL(devSoundConfig);
       
  2056 		//ReNegotiateL();
       
  2057 		}
       
  2058 	else
       
  2059 		User::Leave(KErrNotSupported);
       
  2060 
       
  2061 	// [ assert the invariant ]
       
  2062 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2063 
       
  2064 	}
       
  2065 
       
  2066 /**
       
  2067 * MacSetSourceFormatL
       
  2068 * @param aFormatUid
       
  2069 *
       
  2070 */
       
  2071 void CMMFAudioController::MacSetSourceFormatL(TUid aFormatUid)
       
  2072 	{
       
  2073      //[ assert the invaraint ]
       
  2074 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2075 
       
  2076 	// [ precondition that the controller is stopped ]
       
  2077     if( State() != EStopped )
       
  2078 		User::Leave( KErrNotReady );
       
  2079 
       
  2080 	//[ precondition that the data source exists]
       
  2081 	if (!iDataSource)
       
  2082 		User::Leave(KErrNotReady);
       
  2083 
       
  2084 	//[ precondition that we need a format ]
       
  2085 	if( !SourceFormatRequired( *iDataSource ) )
       
  2086 		User::Leave(KErrNotSupported); //cant set source format if source isn't a clip
       
  2087 
       
  2088 	//[ if the format exists and the uid of the requested
       
  2089 	//	format is the same as the existing format then simply
       
  2090 	// return otherwise create a new format ]
       
  2091 	if( !((iSourceFormat) && ( iSourceFormat->ImplementationUid() == aFormatUid)))
       
  2092 		{
       
  2093 		// [ delete the old format regardless ]
       
  2094 		delete iSourceFormat;
       
  2095 		iSourceFormat = NULL;
       
  2096 		iSourceFormat = CMMFFormatDecode::NewL(aFormatUid, iDataSource);
       
  2097 		}
       
  2098 
       
  2099 	//[ assert the invariant ]
       
  2100 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2101 
       
  2102 	//[ assert the post condition that a source format has been constructed ]
       
  2103 	__ASSERT_ALWAYS( (iSourceFormat != NULL), Panic( EPostConditionViolation ));
       
  2104 	}
       
  2105 
       
  2106 /**
       
  2107 * MacSetSinkSampleRateL
       
  2108 * @param aSampleRate
       
  2109 */
       
  2110 void CMMFAudioController::MacSetSinkSampleRateL(TUint aSampleRate)
       
  2111 	{
       
  2112 	//[ assert the invariant ]
       
  2113 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2114 
       
  2115 	// [ assert the precondition that we are stopped ]
       
  2116 	if (State() != EStopped )
       
  2117 		User::Leave(KErrNotReady);
       
  2118 
       
  2119 	if (iSinkFormat)
       
  2120 		{//only applicable to formats
       
  2121 		// don't throw an error if the clip already exists with a different sample rate
       
  2122 		TInt error = iSinkFormat->SetSampleRate(aSampleRate);
       
  2123 		if (error != KErrNone && error != KErrAlreadyExists)
       
  2124 			User::Leave(error);
       
  2125 		}
       
  2126 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2127 		{
       
  2128 		// cast iDataSink to audio output and set sample rate
       
  2129 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2130 
       
  2131 
       
  2132 
       
  2133 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2134 		ConvertFromSampleRateToDevSoundCapsL(aSampleRate, devSoundConfig);
       
  2135 		ao->SoundDevice().SetConfigL(devSoundConfig);
       
  2136 		}
       
  2137 	else
       
  2138 		User::Leave(KErrNotSupported);
       
  2139 
       
  2140 	//[ assert the invariant ]
       
  2141 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2142 	}
       
  2143 
       
  2144 /**
       
  2145 * MacSetSinkNumChannelsL
       
  2146 * @param aNumChannels
       
  2147 *
       
  2148 */
       
  2149 void CMMFAudioController::MacSetSinkNumChannelsL(TUint aNumChannels)
       
  2150 	{
       
  2151 	//[ assert the invariant ]
       
  2152 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2153 
       
  2154 	// [ assert the precondition that we are stopped ]
       
  2155 	if (State() != EStopped )
       
  2156 		User::Leave(KErrNotReady);
       
  2157 
       
  2158 	if (iSinkFormat)
       
  2159 		{//only applicable to formats
       
  2160 		// don't throw an error if the clip already exists with a different number of channels
       
  2161 		TInt error = iSinkFormat->SetNumChannels(aNumChannels);
       
  2162 		if (error != KErrNone && error != KErrAlreadyExists)
       
  2163 			User::Leave(error);
       
  2164 		}
       
  2165 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2166 		{
       
  2167 		// cast iDataSink to audio output and set num channels
       
  2168 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2169 
       
  2170 		//note that it is safe to call SoundDevice()
       
  2171 		//as the controller logs onto the iDataSource when it is added
       
  2172 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2173 		ConvertFromNumChannelsToDevSoundCapsL(aNumChannels, devSoundConfig);
       
  2174 		ao->SoundDevice().SetConfigL(devSoundConfig);
       
  2175 		}
       
  2176 	else
       
  2177 		User::Leave(KErrNotSupported);
       
  2178 
       
  2179 	// [assert the invariant ]
       
  2180 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2181 
       
  2182 	}
       
  2183 
       
  2184 /**
       
  2185 * MacSetSinkFormatL
       
  2186 * @param aFormatUid
       
  2187 *
       
  2188 */
       
  2189 void CMMFAudioController::MacSetSinkFormatL(TUid aFormatUid)
       
  2190 	{
       
  2191     //[ assert the invariant ]
       
  2192 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2193 
       
  2194 	// [ precondition that the controller is stopped ]
       
  2195     if( State() != EStopped )
       
  2196 		User::Leave( KErrNotReady );
       
  2197 
       
  2198 	//[ precondition that the data sink exists]
       
  2199 	if (!iDataSink)
       
  2200 		User::Leave(KErrNotReady);
       
  2201 
       
  2202 	//[ precondition that we need a format ]
       
  2203 	if (!SinkFormatRequired( *iDataSink))
       
  2204 		User::Leave(KErrNotSupported);
       
  2205 
       
  2206 	//[ if the format exists and the uid of the requested
       
  2207 	//	format is the same as the existing format then simply
       
  2208 	// return ]
       
  2209 	if( !((iSinkFormat) && ( iSinkFormat->ImplementationUid() == aFormatUid)))
       
  2210 		{
       
  2211 		// [ delete the old format regardless ]
       
  2212 		delete iSinkFormat;
       
  2213 		iSinkFormat = NULL;
       
  2214 		iSinkFormat = CMMFFormatEncode::NewL(aFormatUid, iDataSink);
       
  2215 		}
       
  2216 
       
  2217 	//[ assert the invariant ]
       
  2218 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2219 
       
  2220 	//[ assert the post condition that a sink format has been constructed ]
       
  2221 	__ASSERT_ALWAYS( (iSinkFormat != NULL), Panic( EPostConditionViolation ));
       
  2222 	}
       
  2223 
       
  2224 
       
  2225 /**
       
  2226 * MacSetCodecL
       
  2227 * @param aSourceDataType
       
  2228 * @param aSinkDataType
       
  2229 *
       
  2230 */
       
  2231 void CMMFAudioController::MacSetCodecL(TFourCC aSourceDataType, TFourCC aSinkDataType)
       
  2232 	{
       
  2233 	//[ assert the invariant ]
       
  2234 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  2235 
       
  2236 	//[ assert the precondition ]
       
  2237 	if(State() != EStopped)
       
  2238 		User::Leave(KErrNotReady);
       
  2239 	
       
  2240 	//pre condition that we have a source format or sink format
       
  2241 	if (!iSourceFormat && !iSinkFormat)
       
  2242 		{
       
  2243 		User::Leave(KErrNotSupported);
       
  2244 		}
       
  2245 	//don't set codec directly  -just set source & sink fourCC codes
       
  2246 	//[  ]
       
  2247 	TInt error(KErrNone);
       
  2248 	if ((iSinkFormat)&&(aSinkDataType != KMMFFourCCCodeNULL))
       
  2249 		{
       
  2250 		error = iSinkFormat->SetSinkDataTypeCode(aSinkDataType,iMediaId);
       
  2251 		}
       
  2252 	else if((iDataSink) && (aSinkDataType != KMMFFourCCCodeNULL))
       
  2253 		{
       
  2254 		error = iDataSink->SetSinkDataTypeCode(aSinkDataType,iMediaId);
       
  2255 		}
       
  2256 	if ((iSourceFormat)&&(!error)&&(aSourceDataType != KMMFFourCCCodeNULL))
       
  2257 		{
       
  2258 		error = iSourceFormat->SetSourceDataTypeCode(aSourceDataType,iMediaId);
       
  2259 		}
       
  2260 	else if ((iDataSource) && (aSourceDataType != KMMFFourCCCodeNULL))
       
  2261 		{
       
  2262 		error = iDataSource->SetSourceDataTypeCode(aSourceDataType,iMediaId);
       
  2263 		}
       
  2264 
       
  2265 	//[ leave if we are not ready or there was an error ]
       
  2266 	User::LeaveIfError(error);
       
  2267 
       
  2268 	//[ assert the invariant ]
       
  2269 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  2270 	}
       
  2271 
       
  2272 /**
       
  2273 * MacSetSourceBitRateL
       
  2274 * @param "TUint"
       
  2275 * Sets the source bit rate
       
  2276 *
       
  2277 */
       
  2278 void CMMFAudioController::MacSetSourceBitRateL(TUint aBitRate)
       
  2279 	{
       
  2280 	//[ assert the invariant ]
       
  2281 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  2282 
       
  2283 	//[ assert the precondition ]
       
  2284 	if(State() != EStopped)
       
  2285 		User::Leave(KErrNotReady);
       
  2286 
       
  2287 	//[ pre condition  that we have a source format]
       
  2288 	if (!iSourceFormat)
       
  2289 		User::Leave(KErrNotSupported);
       
  2290 
       
  2291 	//only applicable to formats
       
  2292 	User::LeaveIfError(iSourceFormat->SetBitRate(aBitRate));
       
  2293 
       
  2294 	//[ assert the set bit rate is the bit rate ]
       
  2295 	__ASSERT_ALWAYS( (aBitRate == iSourceFormat->BitRate()), Panic( EPostConditionViolation ));
       
  2296 
       
  2297 	//[ assert the invariant ]
       
  2298 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2299 	}
       
  2300 
       
  2301 
       
  2302 /**
       
  2303 *
       
  2304 * MacSetSourceDataTypeL
       
  2305 * @param "TFourCC"
       
  2306 *
       
  2307 */
       
  2308 void CMMFAudioController::MacSetSourceDataTypeL(TFourCC aDataType)
       
  2309 	{
       
  2310 	//pre condition we have a source format
       
  2311 	if (!iSourceFormat)
       
  2312 		{
       
  2313 		User::Leave(KErrNotSupported);
       
  2314 		}
       
  2315 	MacSetCodecL(aDataType, KMMFFourCCCodeNULL);
       
  2316 	}
       
  2317 
       
  2318 /**
       
  2319 *
       
  2320 * MacSetSinkBitRateL
       
  2321 * @param "TUint"
       
  2322 *
       
  2323 */
       
  2324 void CMMFAudioController::MacSetSinkBitRateL(TUint aRate)
       
  2325 	{
       
  2326 	//[ assert the invariant ]
       
  2327 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2328 
       
  2329     // [ assert we are stopped ]
       
  2330 	if( State() != EStopped)
       
  2331 		User::Leave( KErrNotReady );
       
  2332 
       
  2333 	//[ pre condition we have a sink format ]
       
  2334 	if (!iSinkFormat)
       
  2335 		User::Leave(KErrNotSupported);
       
  2336 
       
  2337 	//only applicable to formats
       
  2338 	User::LeaveIfError(iSinkFormat->SetBitRate(aRate));
       
  2339 
       
  2340 	//[ assert the set bit rate is the bit rate ]
       
  2341 	__ASSERT_ALWAYS( (aRate == iSinkFormat->BitRate()), Panic( EBadInvariant));
       
  2342 
       
  2343 	//[ assert the invariant ]
       
  2344 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2345 	}
       
  2346 
       
  2347 /**
       
  2348 *
       
  2349 * MacSetSinkDataTypeL
       
  2350 * @param "TFourCC"
       
  2351 *
       
  2352 */
       
  2353 void CMMFAudioController::MacSetSinkDataTypeL(TFourCC aDataType)
       
  2354 	{
       
  2355 	//precondition is that we have a sink format
       
  2356 	if (!iSinkFormat)
       
  2357 		{
       
  2358 		User::Leave(KErrNotSupported);
       
  2359 		}
       
  2360 
       
  2361 	MacSetCodecL(KMMFFourCCCodeNULL, aDataType);
       
  2362 
       
  2363 	if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2364 		{
       
  2365 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2366 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2367 		RArray<TFourCC> dataTypes;
       
  2368 		CleanupClosePushL(dataTypes);
       
  2369 
       
  2370 		//[ set dev sound data type here ]
       
  2371 		ConvertFromDataTypeToDevSoundCapsL(aDataType, devSoundConfig);
       
  2372 		ao->SoundDevice().SetConfigL(devSoundConfig);
       
  2373 		CleanupStack::PopAndDestroy();//dataTypes
       
  2374 		}
       
  2375 	}
       
  2376 
       
  2377 /**
       
  2378 *
       
  2379 * MacGetSourceSampleRateL
       
  2380 * @param "TUint"
       
  2381 *
       
  2382 */
       
  2383 void CMMFAudioController::MacGetSourceSampleRateL(TUint& aRate)
       
  2384 	{
       
  2385 	//[ assert the invariant ]
       
  2386 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2387 
       
  2388 	//[ precondition is that we have a source format ||
       
  2389 	// we have a data source and its an audio input ]
       
  2390 	if( !((iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput)) ||
       
  2391 		( iSourceFormat )))
       
  2392 		User::Leave(KErrNotSupported);
       
  2393 
       
  2394 	if (iSourceFormat)
       
  2395 		{
       
  2396 		aRate = iSourceFormat->SampleRate();
       
  2397 		}
       
  2398 	else
       
  2399 		{
       
  2400 		// cast iDataSource to audio input and query sample rate
       
  2401 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2402 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Config();
       
  2403 		RArray<TUint> rates;
       
  2404 		CleanupClosePushL(rates);
       
  2405 		ConvertFromDevSoundCapsToSampleRatesL(devSoundConfig, rates);
       
  2406 		ASSERT(rates.Count()==1);//make sure we've been given the correct config by devsound
       
  2407 		aRate = rates[0];
       
  2408 		CleanupStack::PopAndDestroy();//rates
       
  2409 		}
       
  2410 
       
  2411 	//[ assert the invariant ]
       
  2412 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2413 	}
       
  2414 
       
  2415 /**
       
  2416 *
       
  2417 * MacGetSourceBitRateL
       
  2418 * @param "TUint"
       
  2419 *
       
  2420 */
       
  2421 void CMMFAudioController::MacGetSourceBitRateL(TUint& aRate)
       
  2422 	{
       
  2423 	//[ assert the invariant ]
       
  2424 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2425 
       
  2426 	// Can only query formats for bit rate - devsound doesn't do bit rates.
       
  2427 	if (!iSourceFormat)
       
  2428 		User::Leave(KErrNotSupported);
       
  2429 
       
  2430 	aRate = iSourceFormat->BitRate();
       
  2431 
       
  2432 	//[ assert the invariant ]
       
  2433 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2434 
       
  2435 	}
       
  2436 
       
  2437 /**
       
  2438 *
       
  2439 * MacGetSourceNumChannelsL
       
  2440 * @param "TUint&"
       
  2441 *
       
  2442 */
       
  2443 void CMMFAudioController::MacGetSourceNumChannelsL(TUint& aNumChannels)
       
  2444 	{
       
  2445 	//[ assert the invariant ]
       
  2446 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2447 
       
  2448 	//[ assert the precondition ]
       
  2449 	if( !((iSourceFormat) ||
       
  2450 		(iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))))
       
  2451 		User::Leave(KErrNotSupported);
       
  2452 
       
  2453 	if (iSourceFormat)
       
  2454 		{
       
  2455 		aNumChannels = iSourceFormat->NumChannels();
       
  2456 		}
       
  2457 	else
       
  2458 		{
       
  2459 		// cast iDataSource to audio input and query num channels
       
  2460 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2461 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Config();
       
  2462 		RArray<TUint> numChannels;
       
  2463 		CleanupClosePushL(numChannels);
       
  2464 		ConvertFromDevSoundCapsToNumChannelsL(devSoundConfig, numChannels);
       
  2465 		ASSERT(numChannels.Count()==1);
       
  2466 		aNumChannels = numChannels[0];
       
  2467 		CleanupStack::PopAndDestroy();//numChannels
       
  2468 		}
       
  2469 
       
  2470 	//[ assert the invariant ]
       
  2471 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2472 
       
  2473 	}
       
  2474 
       
  2475 /**
       
  2476 *
       
  2477 * MacGetSourceFormatL
       
  2478 * @param "TUid"
       
  2479 */
       
  2480 void CMMFAudioController::MacGetSourceFormatL(TUid& aFormat)
       
  2481 	{
       
  2482 	//[ assert the invariant ]
       
  2483 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2484 
       
  2485 	//[ precondition we have a format ]
       
  2486 	if (!iSourceFormat)
       
  2487 		User::Leave(KErrNotSupported);
       
  2488 
       
  2489 	// [ get the source format uid ]
       
  2490 	aFormat = iSourceFormat->ImplementationUid();
       
  2491 
       
  2492 	//[ assert the invariant ]
       
  2493 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant));
       
  2494 
       
  2495 	}
       
  2496 
       
  2497 /**
       
  2498 *
       
  2499 * MacGetSourceDataTypeL
       
  2500 * @param "TFourCC&"
       
  2501 *
       
  2502 */
       
  2503 void CMMFAudioController::MacGetSourceDataTypeL(TFourCC& aDataType)
       
  2504 	{
       
  2505 	if (iSourceFormat)
       
  2506 		aDataType = iSourceFormat->SourceDataTypeCode(TMediaId(KUidMediaTypeAudio));
       
  2507 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2508 		{
       
  2509 		// cast iDataSource to audio input and query num channels
       
  2510 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2511 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Config();
       
  2512 		RArray<TFourCC> dataTypes;
       
  2513 		CleanupClosePushL(dataTypes);
       
  2514 		ConvertFromDevSoundCapsToDataTypesL(devSoundConfig, dataTypes);
       
  2515 		ASSERT(dataTypes.Count()==1);
       
  2516 		aDataType = dataTypes[0];
       
  2517 		CleanupStack::PopAndDestroy();//dataTypes
       
  2518 		}
       
  2519 	else
       
  2520 		User::Leave(KErrNotSupported);
       
  2521 	}
       
  2522 
       
  2523 /**
       
  2524 *
       
  2525 * MacGetSinkSampleRateL
       
  2526 * @param "TUint&"
       
  2527 *
       
  2528 */
       
  2529 
       
  2530 void CMMFAudioController::MacGetSinkSampleRateL(TUint& aRate)
       
  2531 	{
       
  2532 	if (iSinkFormat)
       
  2533 		aRate = iSinkFormat->SampleRate();
       
  2534 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2535 		{
       
  2536 		// cast iDataSink to audio output and query sample rate
       
  2537 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2538 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2539 		RArray<TUint> rates;
       
  2540 		CleanupClosePushL(rates);
       
  2541 		ConvertFromDevSoundCapsToSampleRatesL(devSoundConfig, rates);
       
  2542 		ASSERT(rates.Count()==1);//make sure we've been given the correct config by devsound
       
  2543 		aRate = rates[0];
       
  2544 		CleanupStack::PopAndDestroy();//rates
       
  2545 		}
       
  2546 	else
       
  2547 		User::Leave(KErrNotSupported);
       
  2548 	}
       
  2549 
       
  2550 /**
       
  2551 *
       
  2552 * MacGetSinkBitRateL
       
  2553 * @param "TUint&"
       
  2554 *
       
  2555 */
       
  2556 void CMMFAudioController::MacGetSinkBitRateL(TUint& aRate)
       
  2557 	{
       
  2558 	if (iSinkFormat)
       
  2559 		aRate = iSinkFormat->BitRate();
       
  2560 	else
       
  2561 		User::Leave(KErrNotSupported);
       
  2562 	}
       
  2563 
       
  2564 /**
       
  2565 *
       
  2566 * MacGetSinkNumChannelsL
       
  2567 * @param "TUint&"
       
  2568 *
       
  2569 */
       
  2570 void CMMFAudioController::MacGetSinkNumChannelsL(TUint& aNumChannels)
       
  2571 	{
       
  2572 	if (iSinkFormat)
       
  2573 		aNumChannels = iSinkFormat->NumChannels();
       
  2574 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2575 		{
       
  2576 		// cast iDataSink to audio output and query num channels
       
  2577 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2578 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2579 		RArray<TUint> numChannels;
       
  2580 		CleanupClosePushL(numChannels);
       
  2581 		ConvertFromDevSoundCapsToNumChannelsL(devSoundConfig, numChannels);
       
  2582 		ASSERT(numChannels.Count()==1);
       
  2583 		aNumChannels = numChannels[0];
       
  2584 		CleanupStack::PopAndDestroy();//numChannels
       
  2585 		}
       
  2586 	else
       
  2587 		User::Leave(KErrNotSupported);
       
  2588 	}
       
  2589 
       
  2590 /**
       
  2591 *
       
  2592 * MacGetSinkFormatL
       
  2593 * @param "TUid&"
       
  2594 *
       
  2595 */
       
  2596 void CMMFAudioController::MacGetSinkFormatL(TUid& aFormat)
       
  2597 	{
       
  2598 	if (iSinkFormat)
       
  2599 		aFormat = iSinkFormat->ImplementationUid();
       
  2600 	else
       
  2601 		User::Leave(KErrNotSupported);
       
  2602 	}
       
  2603 
       
  2604 /**
       
  2605 *
       
  2606 * MacGetSinkDataTypeL
       
  2607 * @param "TFourCC&"
       
  2608 *
       
  2609 */
       
  2610 void CMMFAudioController::MacGetSinkDataTypeL(TFourCC& aDataType)
       
  2611 	{
       
  2612 	if (iSinkFormat)
       
  2613 		aDataType = iSinkFormat->SinkDataTypeCode(TMediaId(KUidMediaTypeAudio));
       
  2614 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2615 		{
       
  2616 		// cast iDataSink to audio output and query data type
       
  2617 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2618 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Config();
       
  2619 		RArray<TFourCC> dataTypes;
       
  2620 		CleanupClosePushL(dataTypes);
       
  2621 		ConvertFromDevSoundCapsToDataTypesL(devSoundConfig, dataTypes);
       
  2622 		ASSERT(dataTypes.Count()==1);
       
  2623 		aDataType = dataTypes[0];
       
  2624 		CleanupStack::PopAndDestroy();//dataTypes
       
  2625 		}
       
  2626 	else
       
  2627 		User::Leave(KErrNotSupported);
       
  2628 	}
       
  2629 
       
  2630 /**
       
  2631 *
       
  2632 * MacGetSupportedSourceSampleRatesL
       
  2633 * @param "RArray<TUint>&"
       
  2634 *
       
  2635 */
       
  2636 void CMMFAudioController::MacGetSupportedSourceSampleRatesL(RArray<TUint>& aSupportedRates)
       
  2637 	{
       
  2638 	aSupportedRates.Reset();
       
  2639 	if (iSourceFormat)
       
  2640 		iSourceFormat->GetSupportedSampleRatesL(aSupportedRates);
       
  2641 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2642 		{
       
  2643 		// cast iDataSource to audio input and query supported sample rates
       
  2644 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2645 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Capabilities();
       
  2646 		ConvertFromDevSoundCapsToSampleRatesL(devSoundConfig, aSupportedRates);
       
  2647 		}
       
  2648 	else
       
  2649 		User::Leave(KErrNotSupported);
       
  2650 	}
       
  2651 
       
  2652 /**
       
  2653 *
       
  2654 * MacGetSupportedSourceBitRatesL
       
  2655 * @param "RArray<TUint>&"
       
  2656 *
       
  2657 */
       
  2658 void CMMFAudioController::MacGetSupportedSourceBitRatesL(RArray<TUint>& aSupportedRates)
       
  2659 	{
       
  2660 	aSupportedRates.Reset();
       
  2661 	if (iSourceFormat)
       
  2662 		iSourceFormat->GetSupportedBitRatesL(aSupportedRates);
       
  2663 	else
       
  2664 		User::Leave(KErrNotSupported);
       
  2665 	}
       
  2666 
       
  2667 /***
       
  2668 *
       
  2669 * MacGetSupportedSourceNumChannelsL
       
  2670 * @param "RArray<TUint>&"
       
  2671 *
       
  2672 */
       
  2673 void CMMFAudioController::MacGetSupportedSourceNumChannelsL(RArray<TUint>& aSupportedChannels)
       
  2674 	{
       
  2675 	aSupportedChannels.Reset();
       
  2676 	if (iSourceFormat)
       
  2677 		iSourceFormat->GetSupportedNumChannelsL(aSupportedChannels);
       
  2678 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2679 		{
       
  2680 		// cast iDataSource to audio input and query supported num channels
       
  2681 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2682 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Capabilities();
       
  2683 		ConvertFromDevSoundCapsToNumChannelsL(devSoundConfig, aSupportedChannels);
       
  2684 		}
       
  2685 	else
       
  2686 		User::Leave(KErrNotSupported);
       
  2687 	}
       
  2688 
       
  2689 /***
       
  2690 *
       
  2691 * MacGetSupportedSourceDataTypesL
       
  2692 * @param "RArray<TFourCC>&"
       
  2693 *
       
  2694 */
       
  2695 void CMMFAudioController::MacGetSupportedSourceDataTypesL(RArray<TFourCC>& aSupportedDataTypes)
       
  2696 	{
       
  2697 	aSupportedDataTypes.Reset();
       
  2698 	if (iSourceFormat)
       
  2699 		iSourceFormat->GetSupportedDataTypesL(TMediaId(KUidMediaTypeAudio), aSupportedDataTypes);
       
  2700 	else if (iDataSource && (iDataSource->DataSourceType()==KUidMmfAudioInput))
       
  2701 		{
       
  2702 		// cast iDataSource to audio input and query supported data types
       
  2703 		MMMFAudioInput* ai = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  2704 		TMMFCapabilities devSoundConfig = ai->SoundDevice().Capabilities();
       
  2705 		ConvertFromDevSoundCapsToDataTypesL(devSoundConfig, aSupportedDataTypes);
       
  2706 		}
       
  2707 	else
       
  2708 		User::Leave(KErrNotSupported);
       
  2709 	}
       
  2710 
       
  2711 /***
       
  2712 *
       
  2713 * MacGetSupportedSinkSampleRatesL
       
  2714 * @param "RArray<TUint>& "
       
  2715 *
       
  2716 */
       
  2717 void CMMFAudioController::MacGetSupportedSinkSampleRatesL(RArray<TUint>& aSupportedRates)
       
  2718 	{
       
  2719 	aSupportedRates.Reset();
       
  2720 	if (iSinkFormat)
       
  2721 		iSinkFormat->GetSupportedSampleRatesL(aSupportedRates);
       
  2722 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2723 		{
       
  2724 		// cast iDataSink to audio output and query supported sample rates
       
  2725 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2726 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Capabilities();
       
  2727 		ConvertFromDevSoundCapsToSampleRatesL(devSoundConfig, aSupportedRates);
       
  2728 		}
       
  2729 	else
       
  2730 		User::Leave(KErrNotSupported);
       
  2731 	}
       
  2732 
       
  2733 /***
       
  2734 *
       
  2735 * MacGetSupportedSinkBitRatesL
       
  2736 * @param RArray<TUint>&
       
  2737 *
       
  2738 */
       
  2739 void CMMFAudioController::MacGetSupportedSinkBitRatesL(RArray<TUint>& aSupportedRates)
       
  2740 	{
       
  2741 	if (iSinkFormat)
       
  2742 		iSinkFormat->GetSupportedBitRatesL(aSupportedRates);
       
  2743 	else
       
  2744 		User::Leave(KErrNotSupported);
       
  2745 	}
       
  2746 
       
  2747 /***
       
  2748 *
       
  2749 * MacGetSupportedSinkNumChannelsL
       
  2750 * @param RArray<TUint>&
       
  2751 *
       
  2752 */
       
  2753 void CMMFAudioController::MacGetSupportedSinkNumChannelsL(RArray<TUint>& aSupportedChannels)
       
  2754 	{
       
  2755 	aSupportedChannels.Reset();
       
  2756 	if (iSinkFormat)
       
  2757 		iSinkFormat->GetSupportedNumChannelsL(aSupportedChannels);
       
  2758 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2759 		{
       
  2760 		// cast iDataSink to audio output and query supported channels
       
  2761 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2762 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Capabilities();
       
  2763 		ConvertFromDevSoundCapsToNumChannelsL(devSoundConfig, aSupportedChannels);
       
  2764 		}
       
  2765 	else
       
  2766 		User::Leave(KErrNotSupported);
       
  2767 	}
       
  2768 
       
  2769 /***
       
  2770 *
       
  2771 * MacGetSupportedSinkDataTypesL
       
  2772 * @param "RArray<TFourCC>&"
       
  2773 */
       
  2774 void CMMFAudioController::MacGetSupportedSinkDataTypesL(RArray<TFourCC>& aSupportedDataTypes)
       
  2775 	{
       
  2776 	aSupportedDataTypes.Reset();
       
  2777 	if (iSinkFormat)
       
  2778 		iSinkFormat->GetSupportedDataTypesL(TMediaId(KUidMediaTypeAudio), aSupportedDataTypes);
       
  2779 	else if (iDataSink && (iDataSink->DataSinkType()==KUidMmfAudioOutput))
       
  2780 		{
       
  2781 		// cast iDataSink to audio output and query supported data types
       
  2782 		MMMFAudioOutput* ao = STATIC_CAST(MMMFAudioOutput*, iDataSink);
       
  2783 		TMMFCapabilities devSoundConfig = ao->SoundDevice().Capabilities();
       
  2784 		ConvertFromDevSoundCapsToDataTypesL(devSoundConfig, aSupportedDataTypes);
       
  2785 		}
       
  2786 	else
       
  2787 		User::Leave(KErrNotSupported);
       
  2788 	}
       
  2789 
       
  2790 /**
       
  2791 *
       
  2792 * ConvertFromDevSoundCapsToSampleRatesL
       
  2793 * @param "const TMMFCapabilities& "
       
  2794 * @param "RArray<TUint>&"
       
  2795 *
       
  2796 */
       
  2797 void CMMFAudioController::ConvertFromDevSoundCapsToSampleRatesL(const TMMFCapabilities& aDevSoundCaps, RArray<TUint>& aSampleRates)
       
  2798 	{
       
  2799 	if (aDevSoundCaps.iRate & EMMFSampleRate8000Hz)
       
  2800 		User::LeaveIfError(aSampleRates.Append(KSampleRate8000Hz));
       
  2801 	if (aDevSoundCaps.iRate & EMMFSampleRate11025Hz)
       
  2802 		User::LeaveIfError(aSampleRates.Append(KSampleRate11025Hz));
       
  2803 	if (aDevSoundCaps.iRate & EMMFSampleRate12000Hz)
       
  2804 		User::LeaveIfError(aSampleRates.Append(KSampleRate12000Hz));
       
  2805 	if (aDevSoundCaps.iRate & EMMFSampleRate16000Hz)
       
  2806 		User::LeaveIfError(aSampleRates.Append(KSampleRate16000Hz));
       
  2807 	if (aDevSoundCaps.iRate & EMMFSampleRate22050Hz)
       
  2808 		User::LeaveIfError(aSampleRates.Append(KSampleRate22050Hz));
       
  2809 	if (aDevSoundCaps.iRate & EMMFSampleRate24000Hz)
       
  2810 		User::LeaveIfError(aSampleRates.Append(KSampleRate24000Hz));
       
  2811 	if (aDevSoundCaps.iRate & EMMFSampleRate32000Hz)
       
  2812 		User::LeaveIfError(aSampleRates.Append(KSampleRate32000Hz));
       
  2813 	if (aDevSoundCaps.iRate & EMMFSampleRate44100Hz)
       
  2814 		User::LeaveIfError(aSampleRates.Append(KSampleRate44100Hz));
       
  2815 	if (aDevSoundCaps.iRate & EMMFSampleRate48000Hz)
       
  2816 		User::LeaveIfError(aSampleRates.Append(KSampleRate48000Hz));
       
  2817 	if (aDevSoundCaps.iRate & EMMFSampleRate64000Hz)
       
  2818 		User::LeaveIfError(aSampleRates.Append(KSampleRate64000Hz));
       
  2819 	if (aDevSoundCaps.iRate & EMMFSampleRate88200Hz)
       
  2820 		User::LeaveIfError(aSampleRates.Append(KSampleRate88200Hz));
       
  2821 	if (aDevSoundCaps.iRate & EMMFSampleRate96000Hz)
       
  2822 		User::LeaveIfError(aSampleRates.Append(KSampleRate96000Hz));
       
  2823 	}
       
  2824 
       
  2825 /**
       
  2826 *
       
  2827 * ConvertFromDevSoundCapsToNumChannelsL
       
  2828 * @param "const TMMFCapabilities&"
       
  2829 * @param "RArray<TUint>&"
       
  2830 *
       
  2831 */
       
  2832 void CMMFAudioController::ConvertFromDevSoundCapsToNumChannelsL(const TMMFCapabilities& aDevSoundCaps, RArray<TUint>& aNumChannels)
       
  2833 	{
       
  2834 	if (aDevSoundCaps.iChannels & EMMFMono)
       
  2835 		User::LeaveIfError(aNumChannels.Append(KNumChannelsMono));
       
  2836 	if (aDevSoundCaps.iChannels & EMMFStereo)
       
  2837 		User::LeaveIfError(aNumChannels.Append(KNumChannelsStereo));
       
  2838 	}
       
  2839 
       
  2840 /**
       
  2841 *
       
  2842 * ConvertFromDevSoundCapsToDataTypesL
       
  2843 * @param "const TMMFCapabilities&"
       
  2844 * @param "TMMFCapabilities& aDevSoundCaps, RArray<TFourCC>&"
       
  2845 *
       
  2846 */
       
  2847 void CMMFAudioController::ConvertFromDevSoundCapsToDataTypesL(const TMMFCapabilities& aDevSoundCaps, RArray<TFourCC>& aDataTypes)
       
  2848 	{
       
  2849 	if (aDevSoundCaps.iEncoding & EMMFSoundEncoding8BitPCM)
       
  2850 		User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM8));
       
  2851 	if (aDevSoundCaps.iEncoding & EMMFSoundEncoding16BitPCM)
       
  2852 		User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM16));
       
  2853 	if (aDevSoundCaps.iEncoding & EMMFSoundEncoding8BitALaw)
       
  2854 		User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeALAW));
       
  2855 	if (aDevSoundCaps.iEncoding & EMMFSoundEncoding8BitMuLaw)
       
  2856 		User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeMuLAW));
       
  2857 	}
       
  2858 
       
  2859 /**
       
  2860 *
       
  2861 * ConvertFromSampleRateToDevSoundCapsL
       
  2862 * @param "TUint"
       
  2863 * @param "TMMFCapabilities&"
       
  2864 *
       
  2865 */
       
  2866 void CMMFAudioController::ConvertFromSampleRateToDevSoundCapsL(TUint aSampleRate, TMMFCapabilities& aDevSoundCaps)
       
  2867 	{
       
  2868 	if (aSampleRate == KSampleRate8000Hz)
       
  2869 		aDevSoundCaps.iRate = EMMFSampleRate8000Hz;
       
  2870 	else if (aSampleRate == KSampleRate11025Hz)
       
  2871 		aDevSoundCaps.iRate = EMMFSampleRate11025Hz;
       
  2872 	else if (aSampleRate == KSampleRate12000Hz)
       
  2873 		aDevSoundCaps.iRate = EMMFSampleRate12000Hz;
       
  2874 	else if (aSampleRate == KSampleRate16000Hz)
       
  2875 		aDevSoundCaps.iRate = EMMFSampleRate16000Hz;
       
  2876 	else if (aSampleRate == KSampleRate22050Hz)
       
  2877 		aDevSoundCaps.iRate = EMMFSampleRate22050Hz;
       
  2878 	else if (aSampleRate == KSampleRate24000Hz)
       
  2879 		aDevSoundCaps.iRate = EMMFSampleRate24000Hz;
       
  2880 	else if (aSampleRate == KSampleRate32000Hz)
       
  2881 		aDevSoundCaps.iRate = EMMFSampleRate32000Hz;
       
  2882 	else if (aSampleRate == KSampleRate44100Hz)
       
  2883 		aDevSoundCaps.iRate = EMMFSampleRate44100Hz;
       
  2884 	else if (aSampleRate == KSampleRate48000Hz)
       
  2885 		aDevSoundCaps.iRate = EMMFSampleRate48000Hz;
       
  2886 	else if (aSampleRate == KSampleRate64000Hz)
       
  2887 		aDevSoundCaps.iRate = EMMFSampleRate64000Hz;
       
  2888 	else if (aSampleRate == KSampleRate88200Hz)
       
  2889 		aDevSoundCaps.iRate = EMMFSampleRate88200Hz;
       
  2890 	else if (aSampleRate == KSampleRate96000Hz)
       
  2891 		aDevSoundCaps.iRate = EMMFSampleRate96000Hz;
       
  2892 	else
       
  2893 		User::Leave(KErrNotSupported);
       
  2894 	}
       
  2895 
       
  2896 /**
       
  2897 *
       
  2898 * ConvertFromNumChannelsToDevSoundCapsL
       
  2899 * @param "TUint"
       
  2900 * @param  "TMMFCapabilities&"
       
  2901 *
       
  2902 */
       
  2903 void CMMFAudioController::ConvertFromNumChannelsToDevSoundCapsL(TUint aNumChannels, TMMFCapabilities& aDevSoundCaps)
       
  2904 	{
       
  2905 	if (aNumChannels == KNumChannelsMono)
       
  2906 		aDevSoundCaps.iChannels = EMMFMono;
       
  2907 	else if (aNumChannels == KNumChannelsStereo)
       
  2908 		aDevSoundCaps.iChannels = EMMFStereo;
       
  2909 	else
       
  2910 		User::Leave(KErrNotSupported);
       
  2911 	}
       
  2912 
       
  2913 /**
       
  2914 *
       
  2915 * ConvertFromDataTypeToDevSoundCapsL
       
  2916 * @param "TFourCC"
       
  2917 * @param "TMMFCapabilities&"
       
  2918 *
       
  2919 */
       
  2920 void CMMFAudioController::ConvertFromDataTypeToDevSoundCapsL(TFourCC aDataType, TMMFCapabilities& aDevSoundCaps)
       
  2921 	{
       
  2922 	if (aDataType == KMMFFourCCCodePCM8)
       
  2923 		aDevSoundCaps.iEncoding = EMMFSoundEncoding8BitPCM;
       
  2924 	else if (aDataType == KMMFFourCCCodePCM16)
       
  2925 		aDevSoundCaps.iEncoding = EMMFSoundEncoding16BitPCM;
       
  2926 	else if (aDataType == KMMFFourCCCodeALAW)
       
  2927 		aDevSoundCaps.iEncoding = EMMFSoundEncoding8BitALaw;
       
  2928 	else if (aDataType == KMMFFourCCCodeMuLAW)
       
  2929 		aDevSoundCaps.iEncoding = EMMFSoundEncoding8BitMuLaw;
       
  2930 	else
       
  2931 		User::Leave(KErrNotSupported);
       
  2932 	}
       
  2933 
       
  2934 /**
       
  2935 * IsValidStateTransition
       
  2936 * The function validates a state transition from iState to aState
       
  2937 * and returns ETrue if the transition is allowed.
       
  2938 * @internalTechnology
       
  2939 * @param TControllerState
       
  2940 * @returns "TBool"
       
  2941 */
       
  2942 TBool CMMFAudioController::IsValidStateTransition( TControllerState aState ) const
       
  2943 	{
       
  2944 	 TBool result = ETrue ;
       
  2945 	//[ assert the precondition that aState is a valid State ]
       
  2946 	__ASSERT_ALWAYS( IsValidState(aState), Panic( EBadArgument ) );
       
  2947 	//[ assert the invariant that iState is a valid State ]
       
  2948 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ));
       
  2949 
       
  2950 	// [ check the valid state transitions ]
       
  2951 	  // the only invalid transition is
       
  2952 	  // stopped to playing
       
  2953 	if( ( iState == EStopped ) && ( aState == EPlaying ))
       
  2954 		{
       
  2955          result = EFalse ;
       
  2956 		}
       
  2957 
       
  2958 	//[ assert the invariant that iState is a valid State ]
       
  2959 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ));
       
  2960 
       
  2961 	return result ;
       
  2962 	}
       
  2963 
       
  2964 /*
       
  2965 * Invariant
       
  2966 * @internalTechnology
       
  2967 * @returns "TBool"
       
  2968 * This function returns whether the invariant is valid
       
  2969 */
       
  2970 TBool  CMMFAudioController::Invariant() const
       
  2971 	{
       
  2972 	//[ The invariant is for now defined
       
  2973 	// as simply being in the correct state and
       
  2974 	// having iDataPath defined ]
       
  2975 	return ( iDataPath )&& IsValidState( iState);
       
  2976 	}
       
  2977 
       
  2978 /*
       
  2979 * SetState
       
  2980 *  This function sets the state of the controller.
       
  2981 * @internalTechnology
       
  2982 * @returns "TBool"
       
  2983 */
       
  2984 TBool CMMFAudioController::SetState(TControllerState aState)
       
  2985 	{
       
  2986 	TBool result = ETrue;
       
  2987 	//[ assert the precondition that the state is a valid state ]
       
  2988    	__ASSERT_ALWAYS( IsValidState( aState),  Panic( EBadArgument ) );
       
  2989 	//[ assert the invariant the current state is valid ]
       
  2990 	__ASSERT_ALWAYS( Invariant(),  Panic( EBadInvariant ) );
       
  2991     //[ only allow valid state transitions ]
       
  2992 	if( IsValidStateTransition( aState ) )
       
  2993 		{
       
  2994 		//[ valid state transition set the state]
       
  2995 		iState = aState ;
       
  2996 		}
       
  2997 	else
       
  2998 		{
       
  2999 		//[ invalid state transition return EFalse ]
       
  3000 		result = EFalse;
       
  3001 		}
       
  3002 	// [ assert the invariant on the state ]
       
  3003 	__ASSERT_ALWAYS( Invariant(), Panic( EBadState ));
       
  3004 
       
  3005 	return result ;
       
  3006 	}
       
  3007 
       
  3008 /*
       
  3009 * IsValidState
       
  3010 * checks whether a state is a valid
       
  3011 * @internalTechnology
       
  3012 * @returns "TBool"
       
  3013 * @param TControllerState
       
  3014 */
       
  3015 TBool  CMMFAudioController::IsValidState( TControllerState aState ) const
       
  3016 	{
       
  3017 	TBool result = EFalse;
       
  3018      if(( aState >= EStopped ) && ( aState <= EPlaying ))
       
  3019 		 {
       
  3020           result = ETrue;
       
  3021 		 }
       
  3022 	 return result;
       
  3023 	}
       
  3024 
       
  3025 /**
       
  3026 * State
       
  3027 * The function State returns the current state of the audio controller
       
  3028 * @internalTechnology
       
  3029 * @returns "TControllerState"
       
  3030 */
       
  3031 CMMFAudioController::TControllerState CMMFAudioController::State() const
       
  3032 	{
       
  3033 	__ASSERT_ALWAYS( Invariant(), Panic( EBadInvariant ) );
       
  3034 	return iState;
       
  3035 	}
       
  3036 
       
  3037 /**
       
  3038 *
       
  3039 * SinkFormatRequired
       
  3040 *
       
  3041 */
       
  3042 TBool CMMFAudioController::SinkFormatRequired( MDataSink& aDataSink ) const
       
  3043 	{
       
  3044      return (aDataSink.DataSinkType()==KUidMmfFileSink ||
       
  3045 		     aDataSink.DataSinkType()==KUidMmfDescriptorSink);
       
  3046 	}
       
  3047 
       
  3048 /**
       
  3049 *
       
  3050 * SourceFormatRequired
       
  3051 *
       
  3052 */
       
  3053 
       
  3054 TBool CMMFAudioController::SourceFormatRequired(MDataSource& aDataSource) const
       
  3055 	{
       
  3056 	return (aDataSource.DataSourceType()==KUidMmfFileSource ||
       
  3057 		    aDataSource.DataSourceType()==KUidMmfDescriptorSource);
       
  3058 	}
       
  3059 
       
  3060 TInt CMMFAudioController::MdcEvaluateIntent(ContentAccess::TIntent aIntent)
       
  3061 	{
       
  3062 	if (!iDataSource)
       
  3063         {
       
  3064             return KErrNotReady;
       
  3065         }
       
  3066 	
       
  3067 	if (iDataSource->DataSourceType()==KUidMmfFileSource)
       
  3068 		{
       
  3069 		CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
  3070 		TInt err = file->EvaluateIntent(aIntent);
       
  3071 		return err;
       
  3072 		}
       
  3073 	else
       
  3074 		{
       
  3075 		// Evaluating intent will always succeed on sinks that
       
  3076 		// don't support DRM
       
  3077 		return KErrNone;
       
  3078 		}
       
  3079 
       
  3080 	}
       
  3081 
       
  3082 TInt CMMFAudioController::MdcExecuteIntent(ContentAccess::TIntent aIntent)
       
  3083 	{
       
  3084 	
       
  3085 	if (!iDataSource)
       
  3086         {
       
  3087             return KErrNotReady;
       
  3088         }
       
  3089 
       
  3090 	if (iDataSource->DataSourceType()==KUidMmfFileSource)
       
  3091 		{
       
  3092 		CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
  3093 		TInt err = file->ExecuteIntent(aIntent);
       
  3094 		return err;
       
  3095 		}
       
  3096 	else
       
  3097 		{
       
  3098 		// Executing intent will always succeed on sinks that
       
  3099 		// don't support DRM
       
  3100 		return KErrNone;
       
  3101 		}
       
  3102 	}
       
  3103 
       
  3104 TInt CMMFAudioController::MdcDisableAutomaticIntent(TBool aDisableAutoIntent)
       
  3105 	{
       
  3106 	iDisableAutoIntent = aDisableAutoIntent;
       
  3107 	return KErrNone;
       
  3108 	}
       
  3109 
       
  3110 
       
  3111 TInt CMMFAudioController::MdcSetAgentProperty(ContentAccess::TAgentProperty aProperty, TInt aValue)
       
  3112 	{
       
  3113 	
       
  3114 	if (!iDataSource)
       
  3115         {
       
  3116             return KErrNotReady;
       
  3117         }
       
  3118 
       
  3119 	if (iDataSource->DataSourceType()==KUidMmfFileSource)
       
  3120 		{
       
  3121 		CMMFFile* file = static_cast<CMMFFile*>(iDataSource);
       
  3122 		TInt err = file->SetAgentProperty(aProperty, aValue);
       
  3123 		return err;
       
  3124 		}
       
  3125 	else
       
  3126 		{
       
  3127 		return KErrNone;
       
  3128 		}
       
  3129 	}
       
  3130 
       
  3131 void CMMFAudioController::MarnRegisterAsClientL(TUid aEventType,const TDesC8& aNotificationRegistrationData)
       
  3132 	{
       
  3133 	//[ assert the invariant ]
       
  3134 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3135 	//[ precondition that we have a sink]
       
  3136 	if (!iDataSink)
       
  3137 		{
       
  3138 		User::Leave(KErrNotReady);
       
  3139 		}
       
  3140 	//[register the notification ]
       
  3141 	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
  3142 	TInt err = audioOutput->SoundDevice().RegisterAsClient(aEventType, aNotificationRegistrationData);
       
  3143 	User::LeaveIfError(err);
       
  3144 	iRegisterARN = ETrue; 
       
  3145 	//[ assert the invariant ]
       
  3146 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3147 	}
       
  3148 
       
  3149 void CMMFAudioController::MarnCancelRegisterAsClientL(TUid aEventType)
       
  3150 	{
       
  3151 	//[ assert the invariant ]
       
  3152 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3153 	//[ precondition that we have a sink]
       
  3154 	if (!iDataSink)
       
  3155 		{
       
  3156 		User::Leave(KErrNotReady);
       
  3157 		}
       
  3158 	//[cancel the notification ]
       
  3159 	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
  3160 	TInt err = audioOutput->SoundDevice().CancelRegisterAsClient(aEventType);
       
  3161 	User::LeaveIfError(err);
       
  3162     iRegisterARN = EFalse;
       
  3163 	//[ assert the invariant ]
       
  3164 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3165 	}
       
  3166 
       
  3167 void CMMFAudioController::MarnGetResourceNotificationDataL(TUid aEventType,TDes8& aNotificationData)
       
  3168 	{
       
  3169 	//[ assert the invariant ]
       
  3170 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3171 	//[ precondition that we have a sink]
       
  3172 	if (!iDataSink)
       
  3173 		{
       
  3174 		User::Leave(KErrNotReady);
       
  3175 		}
       
  3176 	//[get the notification data]
       
  3177 	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
  3178 	TMMFTimeIntervalMicroSecondsPckg pckg;
       
  3179 	TInt err = audioOutput->SoundDevice().GetResourceNotificationData(aEventType, pckg);
       
  3180 	User::LeaveIfError(err);
       
  3181 
       
  3182 	// aNotificationData contains an offset = the number of samples played.
       
  3183 	// As the client expects a position (in microseconds from the beginning
       
  3184 	// of the clip) we need to convert the data depending on the sample rate
       
  3185 	// Potential issue if using the number of samples played with VBR sampling.
       
  3186 	RArray<TUint> array;
       
  3187 	CleanupClosePushL(array);
       
  3188 	ConvertFromDevSoundCapsToSampleRatesL(audioOutput->SoundDevice().Config(), array);
       
  3189 	// Should only ever have 1 entry in the array
       
  3190 	ASSERT(array.Count() == 1);
       
  3191 	TUint rate = array[0];
       
  3192 	if (rate)
       
  3193 		{
       
  3194 		// Convert the given number of samples using the sample rate
       
  3195 		const TInt KMicroSecsInOneSec = 1000000;
       
  3196 		TTimeIntervalMicroSeconds value = pckg();
       
  3197 		value = TTimeIntervalMicroSeconds(value.Int64() * KMicroSecsInOneSec / rate);
       
  3198 		pckg() = value;
       
  3199 		}
       
  3200 	else
       
  3201 		{
       
  3202 		User::Leave(KErrArgument);
       
  3203 		}
       
  3204 	aNotificationData = pckg;
       
  3205 	CleanupStack::PopAndDestroy();//array
       
  3206 
       
  3207 	//[ assert the invariant ]
       
  3208 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3209 	}
       
  3210 
       
  3211 void CMMFAudioController::MarnWillResumePlayL()
       
  3212 	{
       
  3213 	//[ assert the invariant ]
       
  3214 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3215 	//[ precondition that we have a sink]
       
  3216 	if (!iDataSink)
       
  3217 		{
       
  3218 		User::Leave(KErrNotReady);
       
  3219 		}
       
  3220 	//[wait for the client to resume ]
       
  3221 	MMMFAudioOutput* audioOutput = static_cast<MMMFAudioOutput*>(iDataSink);
       
  3222 	TInt err = audioOutput->SoundDevice().WillResumePlay();
       
  3223 	User::LeaveIfError(err);
       
  3224 	//[ assert the invariant ]
       
  3225 	__ASSERT_ALWAYS( Invariant(), Panic(EBadInvariant));
       
  3226 	}
       
  3227 
       
  3228 // -----------------------------------------------------------------------------
       
  3229 // From MCustomInterfaceCustomCommandImplementor
       
  3230 // Provides the default implementation.
       
  3231 // -----------------------------------------------------------------------------
       
  3232 //
       
  3233 const TMMFMessageDestination& CMMFAudioController::GetCustomInterfaceBuilderL()
       
  3234 	{
       
  3235 	// If an effects manager already exist just return the handle to it
       
  3236 	// otherwise, create one.
       
  3237 	if ( !iCustomInterfaceBuilder )
       
  3238 		{
       
  3239 		CMMFDevSound* mmfDevSound = NULL;
       
  3240 		
       
  3241         if (iDataSource && iSinkFormat) //record
       
  3242     		{
       
  3243     		MMMFAudioInput* audioInput = STATIC_CAST(MMMFAudioInput*, iDataSource);
       
  3244     		mmfDevSound = &audioInput->SoundDevice();
       
  3245     		}
       
  3246         else if (iDataSink && iSourceFormat) //play	
       
  3247             {            	
       
  3248 		    MMMFAudioOutput* audioOutput = STATIC_CAST(MMMFAudioOutput*, iDataSink);		
       
  3249 		    mmfDevSound = &audioOutput->SoundDevice();
       
  3250             }
       
  3251 
       
  3252         if (mmfDevSound)
       
  3253             {            
       
  3254 		    iCustomInterfaceBuilder = CCustomInterfaceBuilder::NewL(MMFObjectContainerL(),
       
  3255 		                                                            *mmfDevSound);
       
  3256         	TBool secure = EFalse;
       
  3257         	secure = CMMFController::IsSecureDrmModeL(); 
       
  3258 			iCustomInterfaceBuilder->SetSecureCustomInterfaces( secure );
       
  3259 
       
  3260     		// Append custom interface builder to the array of MMFObjects
       
  3261 	    	User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*iCustomInterfaceBuilder));
       
  3262             }
       
  3263         else
       
  3264             {
       
  3265         	User::Leave(KErrNotReady);
       
  3266             }            
       
  3267 		}
       
  3268 		
       
  3269 	return iCustomInterfaceBuilder->Handle();
       
  3270 	}