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