os/mm/devsound/devsoundrefplugin/src/controller/audio/MmfAudioToneController.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) 2003-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 "MmfAudioToneController.h"
sl@0
    24
#include <mmf/server/mmfaudiooutput.h>
sl@0
    25
sl@0
    26
/*
sl@0
    27
 A list of panic codes for the Audio Tone Controller
sl@0
    28
@internalTechnology
sl@0
    29
sl@0
    30
 TMmfAudioToneControllerPanics is an enumeration with the following entries:
sl@0
    31
 EBadArgument indicates a bad argument
sl@0
    32
 EBadState indicates a state viaolation
sl@0
    33
 EBadInvariant indicates an invariant violation
sl@0
    34
 EBadReset indicates failed reset
sl@0
    35
 EPostConditionViolation indicates a post condition violation
sl@0
    36
*/
sl@0
    37
enum TMmfAudioToneControllerPanics
sl@0
    38
	{
sl@0
    39
	EBadArgument,
sl@0
    40
	EBadState,
sl@0
    41
	EBadInvariant,
sl@0
    42
	EBadReset,
sl@0
    43
	EPostConditionViolation,
sl@0
    44
	EBadCall,
sl@0
    45
	ENoDataSource,
sl@0
    46
	ENoDataSink,
sl@0
    47
	EMessageAlreadyBeingProcessed,
sl@0
    48
	ENoMessageToProcess,
sl@0
    49
	EStateNotReadyToPlay,
sl@0
    50
	EStateNotConstructed,
sl@0
    51
	EBadStateToGetDataSource,
sl@0
    52
	EBadStateToGetDataSink,
sl@0
    53
	EBadStateForPrime,
sl@0
    54
	EStateNotPrimed,
sl@0
    55
	EBadResetState,
sl@0
    56
	EBadStateToReset,
sl@0
    57
	EBadPlayState,
sl@0
    58
	EBadPauseState,
sl@0
    59
	EBadStateToPause,
sl@0
    60
	EBadStateToStop,
sl@0
    61
	EBadStopState,
sl@0
    62
	ENotReadyForDataSourceRemoval,
sl@0
    63
	EBadDataSourceRemoval,
sl@0
    64
	ENotReadyForDataSinkRemoval,
sl@0
    65
	EBadDataSinkRemoval,
sl@0
    66
	ENotReadyForCustomCommand,
sl@0
    67
	EBadStateAfterNegotiate,
sl@0
    68
	EBadStateToSetPriority,
sl@0
    69
	EBadPriorityState,
sl@0
    70
	EBadInitializeState,
sl@0
    71
	EBadStateToSetVolume,
sl@0
    72
	EBadStateAfterVolumeSet,
sl@0
    73
	EBadStateToGetMaxVolume,
sl@0
    74
	EBadStateAfterGetMaxVolume,
sl@0
    75
	EBadStateToGetVolume,
sl@0
    76
	EBadStateAfterGetVolume,
sl@0
    77
	EBadStateToSetVolumeRamp,
sl@0
    78
	EBadStateAfterSetVolumeRamp,
sl@0
    79
	EBadStateToSetBalance,
sl@0
    80
	EBadStateAfterSetBalance,
sl@0
    81
	EBadStateToGetBalance,
sl@0
    82
	EBadStateAfterGetBalance,
sl@0
    83
	EBadStateForTransition,
sl@0
    84
	EBadStateAfterTransition,
sl@0
    85
	EStateNotValid,
sl@0
    86
	};
sl@0
    87
sl@0
    88
sl@0
    89
/**
sl@0
    90
 Instantiates a new Audio Tone Controller. Usually invoked from ECom
sl@0
    91
 
sl@0
    92
 @internalTechnology
sl@0
    93
 @return CMMFController* bas class for all plugin controllers
sl@0
    94
 */
sl@0
    95
CMMFController* CMMFAudioToneController::NewL()
sl@0
    96
	{
sl@0
    97
	CMMFAudioToneController* self = new(ELeave) CMMFAudioToneController;
sl@0
    98
	CleanupStack::PushL(self);
sl@0
    99
	self->ConstructL();
sl@0
   100
	CleanupStack::Pop( self );
sl@0
   101
	return STATIC_CAST( CMMFController*, self );
sl@0
   102
	}
sl@0
   103
sl@0
   104
sl@0
   105
sl@0
   106
/**
sl@0
   107
2nd Phase constructor
sl@0
   108
sl@0
   109
@internalComponent
sl@0
   110
*/
sl@0
   111
void CMMFAudioToneController::ConstructL()
sl@0
   112
	{
sl@0
   113
	iSourceAndSinkAdded = EFalse;
sl@0
   114
sl@0
   115
	// Construct custom command parsers
sl@0
   116
	CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser = CMMFAudioPlayDeviceCustomCommandParser::NewL(*this);
sl@0
   117
	CleanupStack::PushL(audPlayDevParser);
sl@0
   118
	AddCustomCommandParserL(*audPlayDevParser);
sl@0
   119
	CleanupStack::Pop( audPlayDevParser );//audPlayDevParser
sl@0
   120
sl@0
   121
	CMMFAudioPlayControllerCustomCommandParser* audPlayConParser = CMMFAudioPlayControllerCustomCommandParser::NewL(*this);
sl@0
   122
	CleanupStack::PushL(audPlayConParser);
sl@0
   123
	AddCustomCommandParserL(*audPlayConParser);
sl@0
   124
	CleanupStack::Pop(audPlayConParser);//audPlayConParser
sl@0
   125
	
sl@0
   126
	CMMFAudioPlayControllerSetRepeatsCustomCommandParser* audPlayConSetRepeatsParser = CMMFAudioPlayControllerSetRepeatsCustomCommandParser::NewL(*this);
sl@0
   127
	CleanupStack::PushL(audPlayConSetRepeatsParser);
sl@0
   128
	AddCustomCommandParserL(*audPlayConSetRepeatsParser);
sl@0
   129
	CleanupStack::Pop(audPlayConSetRepeatsParser);
sl@0
   130
	
sl@0
   131
	// [ assert the invariant now that we are constructed ]
sl@0
   132
	__ASSERT_ALWAYS( Invariant(), Panic( EStateNotConstructed));
sl@0
   133
	}
sl@0
   134
sl@0
   135
sl@0
   136
/**
sl@0
   137
1st Phase constructor
sl@0
   138
sl@0
   139
@internalComponent
sl@0
   140
*/
sl@0
   141
sl@0
   142
CMMFAudioToneController::CMMFAudioToneController() : iState(EStopped)
sl@0
   143
	{
sl@0
   144
	}
sl@0
   145
sl@0
   146
/**
sl@0
   147
Destructor
sl@0
   148
sl@0
   149
@internalTechnology
sl@0
   150
*/
sl@0
   151
CMMFAudioToneController::~CMMFAudioToneController()
sl@0
   152
	{
sl@0
   153
	delete iMMFDevSound;
sl@0
   154
	delete iToneSequenceData;
sl@0
   155
	delete iMessage;
sl@0
   156
	}
sl@0
   157
sl@0
   158
/**
sl@0
   159
Adds a data source to the controller 
sl@0
   160
sl@0
   161
@internalTechnology
sl@0
   162
sl@0
   163
@param aSource will provide the data the controller plays
sl@0
   164
*/
sl@0
   165
void CMMFAudioToneController::AddDataSourceL(MDataSource& aSource)
sl@0
   166
	{
sl@0
   167
	//[ assert the invariant ]
sl@0
   168
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateToGetDataSource));
sl@0
   169
sl@0
   170
	// [ precondition that the controller is stopped ]
sl@0
   171
    if( State() != EStopped )
sl@0
   172
		User::Leave( KErrNotReady );
sl@0
   173
	
sl@0
   174
	//[ precondition iData source is not already configured ]
sl@0
   175
	if (iDataSource)
sl@0
   176
		User::Leave(KErrAlreadyExists);
sl@0
   177
sl@0
   178
	//Only works with files or descriptors
sl@0
   179
	if ((aSource.DataSourceType() != KUidMmfFileSource ) && (aSource.DataSourceType() != KUidMmfDescriptorSource))
sl@0
   180
		User::Leave( KErrNotSupported ) ;
sl@0
   181
sl@0
   182
sl@0
   183
	//extract the tone data into a buffer ready to play.
sl@0
   184
	iToneSequenceData = CMMFDataBuffer::NewL(STATIC_CAST(CMMFClip*, &aSource)->Size());
sl@0
   185
sl@0
   186
	aSource.SourcePrimeL();
sl@0
   187
	STATIC_CAST(CMMFClip*, &aSource)->ReadBufferL(iToneSequenceData,0);
sl@0
   188
	aSource.SourceStopL();
sl@0
   189
sl@0
   190
sl@0
   191
	//[ its now safe to set the source ]
sl@0
   192
	iDataSource = &aSource ;
sl@0
   193
sl@0
   194
	//[ assert the post condition ]
sl@0
   195
	__ASSERT_ALWAYS(iDataSource, Panic(EMMFAudioControllerPanicDataSourceDoesNotExist));
sl@0
   196
sl@0
   197
	iDataSource->SetSourcePrioritySettings(iPrioritySettings);
sl@0
   198
	}
sl@0
   199
sl@0
   200
sl@0
   201
sl@0
   202
/**
sl@0
   203
Adds a data sink to the controller 
sl@0
   204
sl@0
   205
@internalTechnology
sl@0
   206
sl@0
   207
@param aSink will accept the data the controller plays
sl@0
   208
*/
sl@0
   209
void CMMFAudioToneController::AddDataSinkL(MDataSink& aSink)
sl@0
   210
	{
sl@0
   211
	//[ assert the invariant ]
sl@0
   212
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateToGetDataSink));
sl@0
   213
sl@0
   214
	// [ precondition that the controller is stopped ]
sl@0
   215
    if( State() != EStopped )
sl@0
   216
		User::Leave( KErrNotReady );
sl@0
   217
sl@0
   218
	// [ assert precondition that sink does not exist ]
sl@0
   219
	if (iMMFDevSound)
sl@0
   220
		User::Leave(KErrAlreadyExists);
sl@0
   221
sl@0
   222
	//Only support playing to audio output 
sl@0
   223
	if (aSink.DataSinkType() != KUidMmfAudioOutput)
sl@0
   224
		User::Leave( KErrNotSupported );
sl@0
   225
sl@0
   226
	iMMFDevSound = CMMFDevSound::NewL();
sl@0
   227
sl@0
   228
	// [ assert post conditions that a sink has been added ]
sl@0
   229
	__ASSERT_ALWAYS(iMMFDevSound, Panic(EMMFAudioControllerPanicDataSinkDoesNotExist));
sl@0
   230
	}
sl@0
   231
	
sl@0
   232
/**
sl@0
   233
Primes the controller, ready for playing
sl@0
   234
sl@0
   235
@internalTechnology
sl@0
   236
sl@0
   237
@param aMessage allows response to client upon completion or error
sl@0
   238
*/
sl@0
   239
void CMMFAudioToneController::PrimeL(TMMFMessage& aMessage)
sl@0
   240
	{
sl@0
   241
	//[ assert the invariant ]
sl@0
   242
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateForPrime));
sl@0
   243
sl@0
   244
	//[ assert the precondition ( in a friendly way for this api 
sl@0
   245
	// that we are either stopped or primed already ]
sl@0
   246
	if(!(( State() == EStopped ) || (State() == EPrimed )))
sl@0
   247
		User::Leave( KErrNotReady );
sl@0
   248
sl@0
   249
	// [ precondition we have a data source & sink and aren't already processing a message]
sl@0
   250
	__ASSERT_ALWAYS( iDataSource, Panic( ENoDataSource));
sl@0
   251
	__ASSERT_ALWAYS( iMMFDevSound, Panic( ENoDataSink));
sl@0
   252
	__ASSERT_ALWAYS( !iMessage, Panic( EMessageAlreadyBeingProcessed ));
sl@0
   253
sl@0
   254
	if (iState == EStopped)
sl@0
   255
		{
sl@0
   256
	
sl@0
   257
		iMessage = new(ELeave) TMMFMessage(aMessage); //store message
sl@0
   258
		__ASSERT_ALWAYS( iMessage, Panic( EPostConditionViolation )); //check if message created sucessfully
sl@0
   259
		SetState(EPriming);
sl@0
   260
sl@0
   261
		TRAPD(err,NegotiateL());
sl@0
   262
		if(err != KErrNone)
sl@0
   263
			{
sl@0
   264
			SetState( EStopped );
sl@0
   265
			delete iMessage;
sl@0
   266
			iMessage = NULL;
sl@0
   267
			User::Leave(err);
sl@0
   268
			}
sl@0
   269
		}
sl@0
   270
	
sl@0
   271
	__ASSERT_ALWAYS( Invariant(), Panic( EStateNotPrimed ) );
sl@0
   272
sl@0
   273
	}
sl@0
   274
sl@0
   275
/**
sl@0
   276
Primes the controller, ready for playingAdds a data sink to the controller 
sl@0
   277
sl@0
   278
@internalTechnology
sl@0
   279
*/
sl@0
   280
void CMMFAudioToneController::PrimeL()
sl@0
   281
	{
sl@0
   282
	Panic(EBadCall);
sl@0
   283
	}
sl@0
   284
sl@0
   285
/**
sl@0
   286
This method resets the controller
sl@0
   287
sl@0
   288
@internalTechnology
sl@0
   289
*/
sl@0
   290
void CMMFAudioToneController::ResetL()
sl@0
   291
	{
sl@0
   292
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateToReset ) );
sl@0
   293
sl@0
   294
	// Stop recording if it's not stopped,
sl@0
   295
	if (State() != EStopped)
sl@0
   296
		{
sl@0
   297
		StopL();
sl@0
   298
		}
sl@0
   299
sl@0
   300
	//[ ensure loggoff of source and sink ]
sl@0
   301
	iDataSource = NULL ;
sl@0
   302
	delete iMMFDevSound; iMMFDevSound = NULL ;
sl@0
   303
	iSourceAndSinkAdded = EFalse;
sl@0
   304
	delete iMessage;
sl@0
   305
	iMessage = NULL;
sl@0
   306
	
sl@0
   307
sl@0
   308
	// [ assert the invariant]
sl@0
   309
	__ASSERT_ALWAYS( Invariant(), Panic( EBadResetState ) );
sl@0
   310
sl@0
   311
	__ASSERT_ALWAYS( ResetPostCondition(), Panic( EBadReset ));
sl@0
   312
	__ASSERT_ALWAYS( Invariant(), Panic(EBadState));
sl@0
   313
	}
sl@0
   314
sl@0
   315
/**
sl@0
   316
This function determnines if the reset post condition is valid
sl@0
   317
sl@0
   318
@internalComponent
sl@0
   319
*/
sl@0
   320
TBool CMMFAudioToneController::ResetPostCondition() const
sl@0
   321
	{
sl@0
   322
     TBool result = EFalse ;
sl@0
   323
	if((iMMFDevSound == NULL)  &&
sl@0
   324
	(iDataSource == NULL)  && 
sl@0
   325
	(State() == EStopped))
sl@0
   326
		{
sl@0
   327
         result = ETrue;
sl@0
   328
		}
sl@0
   329
    return result;
sl@0
   330
	}
sl@0
   331
sl@0
   332
sl@0
   333
/**
sl@0
   334
Start playing the audio tone, passing the data to Dev Sound
sl@0
   335
sl@0
   336
The controller will be put into the EPlaying state
sl@0
   337
sl@0
   338
@internalTechnology
sl@0
   339
*/
sl@0
   340
void CMMFAudioToneController::PlayL()
sl@0
   341
	{
sl@0
   342
	// [ assert the precondition that the
sl@0
   343
	//   play command is only activated in the primed state]
sl@0
   344
	if ( State() != EPrimed && State() != EPausePlaying)
sl@0
   345
		User::Leave(KErrNotReady);
sl@0
   346
sl@0
   347
	// [ assert the Invariant ]
sl@0
   348
	__ASSERT_ALWAYS( Invariant(), Panic(EStateNotReadyToPlay));
sl@0
   349
sl@0
   350
	if(State() == EPausePlaying && iIsResumeSupported)
sl@0
   351
		{
sl@0
   352
		User::LeaveIfError(iMMFDevSound->Resume());
sl@0
   353
		}
sl@0
   354
	else
sl@0
   355
		{
sl@0
   356
		iMMFDevSound->PlayToneSequenceL(iToneSequenceData->Data());	
sl@0
   357
		}
sl@0
   358
	
sl@0
   359
	SetState( EPlaying );
sl@0
   360
	
sl@0
   361
	//[ assert the post condition we are playing ]
sl@0
   362
	__ASSERT_ALWAYS( (State() == EPlaying ), Panic( EBadState));
sl@0
   363
	//[ assert the invariant ]
sl@0
   364
	__ASSERT_ALWAYS( Invariant(), Panic(EBadPlayState));
sl@0
   365
	}
sl@0
   366
sl@0
   367
/**
sl@0
   368
This should Pause playing of the audio tone. HOWEVER, this is not possible with a 
sl@0
   369
tone sequence. This method is therefore provided as a NOP purely to allow audio
sl@0
   370
clients to operate correctly.
sl@0
   371
sl@0
   372
The controller will be put into the EPrimed state
sl@0
   373
sl@0
   374
@internalTechnology
sl@0
   375
 */
sl@0
   376
void CMMFAudioToneController::PauseL()
sl@0
   377
	{
sl@0
   378
	//[ assert the invariant ]
sl@0
   379
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToPause));
sl@0
   380
sl@0
   381
	__ASSERT_ALWAYS(iMMFDevSound, Panic(EMMFAudioControllerPanicDataSinkDoesNotExist));
sl@0
   382
sl@0
   383
	if(iIsResumeSupported)
sl@0
   384
		{
sl@0
   385
		iMMFDevSound->Pause();
sl@0
   386
		SetState(EPausePlaying);
sl@0
   387
		}
sl@0
   388
	else
sl@0
   389
		{
sl@0
   390
		// If Resume is not supported 
sl@0
   391
		// this method can't do anything, as we have no interface to restart DevSound 
sl@0
   392
		// after pausing a tone. It need to be here however as client utility does
sl@0
   393
		// Pause() Stop() when stopping.
sl@0
   394
		SetState(EPrimed);
sl@0
   395
		}
sl@0
   396
sl@0
   397
	//[ assert the post condition we are stopped ]
sl@0
   398
	__ASSERT_ALWAYS( (State() == EPrimed || State() == EPausePlaying), Panic( EBadState));
sl@0
   399
	//[ assert the invariant ]
sl@0
   400
	__ASSERT_ALWAYS( Invariant(), Panic(EBadPauseState));
sl@0
   401
	}
sl@0
   402
sl@0
   403
/**
sl@0
   404
This stops the tone that is currently playing
sl@0
   405
The controller will be put into the EStopped state
sl@0
   406
sl@0
   407
@internalTechnology
sl@0
   408
*/
sl@0
   409
void CMMFAudioToneController::StopL()
sl@0
   410
	{
sl@0
   411
	//[ assert the invariant ]
sl@0
   412
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToStop));
sl@0
   413
sl@0
   414
	// [ precondition that we are not already stopped 
sl@0
   415
	// && if we are stopped do nothing.
sl@0
   416
	// Due to the asynchronous nature of the controller
sl@0
   417
	// interaction the response to stopped when stopped 
sl@0
   418
	// should not be an error ]
sl@0
   419
	if (State() != EStopped)
sl@0
   420
		{
sl@0
   421
		//[ update state to stopped propogate to devsound ]
sl@0
   422
		iMMFDevSound->Stop();
sl@0
   423
		SetState(EStopped);
sl@0
   424
		}
sl@0
   425
sl@0
   426
	//[ assert the post condition we are stopped ]
sl@0
   427
	__ASSERT_ALWAYS( (State() == EStopped), Panic( EBadState));
sl@0
   428
	//[ assert the invariant ]
sl@0
   429
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStopState));
sl@0
   430
	}
sl@0
   431
sl@0
   432
sl@0
   433
/**
sl@0
   434
Removes a data source form the controller
sl@0
   435
sl@0
   436
@internalTechnology
sl@0
   437
sl@0
   438
@param aDataSource The source that is to be removed.
sl@0
   439
*/
sl@0
   440
void CMMFAudioToneController::RemoveDataSourceL(MDataSource& aDataSource )
sl@0
   441
	{
sl@0
   442
	//[ assert the invariant ]
sl@0
   443
	__ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForDataSourceRemoval) );
sl@0
   444
sl@0
   445
	//[ precondition is that we have a data source ]
sl@0
   446
	if( !iDataSource )
sl@0
   447
		User::Leave(KErrNotReady);
sl@0
   448
sl@0
   449
	//[precondition the data source is the data source we have]
sl@0
   450
	if( iDataSource != &aDataSource )
sl@0
   451
		User::Leave(KErrArgument);
sl@0
   452
sl@0
   453
	//[ the controller is in the stopped state ]
sl@0
   454
	if(State() != EStopped)
sl@0
   455
		User::Leave(KErrNotReady);
sl@0
   456
sl@0
   457
	//[ remove the data sink from the controller and delete the format]
sl@0
   458
     if( iSourceAndSinkAdded )
sl@0
   459
		{
sl@0
   460
		iMMFDevSound->Stop();
sl@0
   461
		iSourceAndSinkAdded = EFalse ;
sl@0
   462
		}
sl@0
   463
sl@0
   464
	 iDataSource = NULL ;
sl@0
   465
		
sl@0
   466
	// [ assert postcondition we are stopped ]
sl@0
   467
	__ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
sl@0
   468
sl@0
   469
	//[ assert postcondition the SourceAndSinkAdded is false ]
sl@0
   470
	__ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
sl@0
   471
	
sl@0
   472
	//[ assert postcondition the data sink  is null ]
sl@0
   473
	__ASSERT_ALWAYS( (iDataSource == NULL ), Panic( EPostConditionViolation ));
sl@0
   474
sl@0
   475
	//[ assert the invariant ]
sl@0
   476
	__ASSERT_ALWAYS( Invariant(), Panic(EBadDataSourceRemoval));
sl@0
   477
	}
sl@0
   478
sl@0
   479
sl@0
   480
/**
sl@0
   481
Removes a data sink form the controller
sl@0
   482
sl@0
   483
@internalTechnology
sl@0
   484
sl@0
   485
@param aDataSink The sink that is to be removed. We donot 
sl@0
   486
use this value, as we only support a single sink. 
sl@0
   487
*/
sl@0
   488
void CMMFAudioToneController::RemoveDataSinkL(MDataSink& /*aDataSink*/)
sl@0
   489
	{
sl@0
   490
	//[ assert the invariant ]
sl@0
   491
	__ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForDataSinkRemoval) );
sl@0
   492
sl@0
   493
	//[ precondition is that we have a data sink ]
sl@0
   494
	if(!iMMFDevSound)
sl@0
   495
		User::Leave(KErrNotReady);
sl@0
   496
sl@0
   497
	//[ the controller is in the stopped state ]
sl@0
   498
	if(State() != EStopped)
sl@0
   499
		User::Leave(KErrNotReady);
sl@0
   500
sl@0
   501
	//[ remove the data sink from the controller and delete the format]
sl@0
   502
     if(iSourceAndSinkAdded)
sl@0
   503
		{
sl@0
   504
		iMMFDevSound->Stop();
sl@0
   505
		iSourceAndSinkAdded = EFalse;
sl@0
   506
		}
sl@0
   507
sl@0
   508
	delete iMMFDevSound; iMMFDevSound = NULL;
sl@0
   509
sl@0
   510
		
sl@0
   511
	// [ assert postcondition we are stopped ]
sl@0
   512
	__ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
sl@0
   513
sl@0
   514
	//[ assert postcondition the SourceAndSinkAdded is false ]
sl@0
   515
	__ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
sl@0
   516
	
sl@0
   517
	//[ assert the invariant ]
sl@0
   518
	__ASSERT_ALWAYS( Invariant(), Panic(EBadDataSinkRemoval));
sl@0
   519
	}
sl@0
   520
sl@0
   521
/**
sl@0
   522
Handles a CustomCommand for the controller. This controller doesn't support Custom Commands
sl@0
   523
sl@0
   524
@internalTechnology
sl@0
   525
@param aMessage
sl@0
   526
*/
sl@0
   527
void CMMFAudioToneController::CustomCommand(TMMFMessage& aMessage)
sl@0
   528
	{
sl@0
   529
	//[ assert the invariant ]
sl@0
   530
	__ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForCustomCommand));
sl@0
   531
	// [ We do not have any custom commands ]
sl@0
   532
	aMessage.Complete(KErrNotSupported);
sl@0
   533
	}
sl@0
   534
sl@0
   535
/**
sl@0
   536
Configures Dev Sound, ready for playing.
sl@0
   537
sl@0
   538
@internalComponent
sl@0
   539
*/
sl@0
   540
void CMMFAudioToneController::NegotiateL()
sl@0
   541
	{
sl@0
   542
	if (!iMMFDevSound)
sl@0
   543
		Panic(EMMFAudioOutputDevSoundNotLoaded);
sl@0
   544
sl@0
   545
	iMMFDevSound->InitializeL(*this, EMMFStateTonePlaying);
sl@0
   546
	iMMFDevSound->SetPrioritySettings(iPrioritySettings);
sl@0
   547
sl@0
   548
	//[ assert the invariant ]
sl@0
   549
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterNegotiate));
sl@0
   550
	}
sl@0
   551
sl@0
   552
/**
sl@0
   553
Set the priority settings that this controller should use to access Dev Sound
sl@0
   554
sl@0
   555
@internalTechnology
sl@0
   556
@param aPrioritySettings The requires priority settings
sl@0
   557
*/
sl@0
   558
void CMMFAudioToneController::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
sl@0
   559
	{
sl@0
   560
	//[ assert the invariant ]
sl@0
   561
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetPriority));
sl@0
   562
sl@0
   563
	//[ assert the precondition ]
sl@0
   564
	if(State() != EStopped)
sl@0
   565
		{
sl@0
   566
		ASSERT(EFalse);		// used to leave here with KErrNotReady
sl@0
   567
		return;
sl@0
   568
		}
sl@0
   569
sl@0
   570
	//[ update the priority settings of the controller]
sl@0
   571
	iPrioritySettings = aPrioritySettings;
sl@0
   572
sl@0
   573
	if (iMMFDevSound)
sl@0
   574
		{
sl@0
   575
		iMMFDevSound->SetPrioritySettings(iPrioritySettings);
sl@0
   576
		}
sl@0
   577
sl@0
   578
	__ASSERT_ALWAYS( Invariant(), Panic(EBadPriorityState));
sl@0
   579
	}
sl@0
   580
sl@0
   581
sl@0
   582
sl@0
   583
/**
sl@0
   584
This method is called by DevSound after initialization, indicating that it has completed and 
sl@0
   585
whether there was an error
sl@0
   586
sl@0
   587
@internalTechnology
sl@0
   588
@param aError the error supplied by Dev Sound
sl@0
   589
*/
sl@0
   590
void CMMFAudioToneController::InitializeComplete(TInt aError)
sl@0
   591
	{
sl@0
   592
	//[ assert the state is EPriming ]
sl@0
   593
	__ASSERT_ALWAYS( ( State() == EPriming ), Panic( EBadState ));
sl@0
   594
	__ASSERT_ALWAYS( iMessage, Panic( ENoMessageToProcess ));
sl@0
   595
	
sl@0
   596
	if(aError != KErrNone)
sl@0
   597
		{
sl@0
   598
		SetState( EStopped );
sl@0
   599
		iMessage->Complete(aError);
sl@0
   600
		}
sl@0
   601
	else 
sl@0
   602
		{
sl@0
   603
		SetState( EPrimed );
sl@0
   604
		iMessage->Complete(aError);
sl@0
   605
		iIsResumeSupported = iMMFDevSound->IsResumeSupported();
sl@0
   606
		}
sl@0
   607
	
sl@0
   608
	delete iMessage;
sl@0
   609
	iMessage = NULL;
sl@0
   610
	
sl@0
   611
	// [ assert the invariant]	
sl@0
   612
	__ASSERT_ALWAYS( Invariant(), Panic( EBadInitializeState ) );
sl@0
   613
	}
sl@0
   614
sl@0
   615
sl@0
   616
/**
sl@0
   617
This method is called by DevSound after it has finished playing a tone sequence, indicating 
sl@0
   618
whether there was an error
sl@0
   619
sl@0
   620
@internalTechnology
sl@0
   621
@param aError the error supplied by DevSound
sl@0
   622
*/
sl@0
   623
void CMMFAudioToneController::ToneFinished(TInt aError)
sl@0
   624
	{
sl@0
   625
	// NB KErrInUse, KErrDied OR KErrAccessDenied may be returned 
sl@0
   626
	// to indicate that the sound device is in use  by another higher 
sl@0
   627
	// priority client.
sl@0
   628
	if (aError == KErrCancel || aError == KErrInUse || 
sl@0
   629
	    aError == KErrDied || aError == KErrAccessDenied)
sl@0
   630
		return;
sl@0
   631
sl@0
   632
	if (aError == KErrUnderflow)
sl@0
   633
		aError = KErrNone;
sl@0
   634
sl@0
   635
	if (State() != EStopped)
sl@0
   636
		{
sl@0
   637
		iMMFDevSound->Stop();
sl@0
   638
		SetState( EStopped );
sl@0
   639
		}
sl@0
   640
sl@0
   641
	//now send event to client...
sl@0
   642
	TMMFEvent event;
sl@0
   643
	event.iEventType = KMMFEventCategoryPlaybackComplete;
sl@0
   644
	event.iErrorCode = aError;
sl@0
   645
	DoSendEventToClient(event);	
sl@0
   646
	}
sl@0
   647
sl@0
   648
sl@0
   649
sl@0
   650
/**
sl@0
   651
Called my DevSound to indicate we have been thrown off H/W by a higher priority
sl@0
   652
sl@0
   653
@internalTechnology
sl@0
   654
@param aEvent contains the reason we have been contacted by DevSound
sl@0
   655
*/
sl@0
   656
void CMMFAudioToneController::SendEventToClient(const TMMFEvent& aEvent)
sl@0
   657
	{
sl@0
   658
	if(State() == EPlaying)
sl@0
   659
		SetState(EStopped);
sl@0
   660
sl@0
   661
	DoSendEventToClient(aEvent);	
sl@0
   662
	}
sl@0
   663
sl@0
   664
sl@0
   665
sl@0
   666
sl@0
   667
/**
sl@0
   668
Sets the playback volume
sl@0
   669
sl@0
   670
@internalTechnology
sl@0
   671
@param aVolume the required volume
sl@0
   672
*/
sl@0
   673
void CMMFAudioToneController::MapdSetVolumeL(TInt aVolume)
sl@0
   674
	{
sl@0
   675
	//[ assert the invariant ]
sl@0
   676
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetVolume));
sl@0
   677
sl@0
   678
	// [  precondition is true for state 
sl@0
   679
	//    we can set the volume in any state ]
sl@0
   680
sl@0
   681
	//[ precondition we have a data sink ]
sl@0
   682
	if (!iMMFDevSound)
sl@0
   683
		User::Leave(KErrNotReady);
sl@0
   684
sl@0
   685
sl@0
   686
	// [ assert the precondition that aVolume is in range ]
sl@0
   687
	TInt maxVolume = iMMFDevSound->MaxVolume();
sl@0
   688
	if( ( aVolume < 0 ) || ( aVolume > maxVolume ))
sl@0
   689
		User::Leave(KErrArgument);
sl@0
   690
	
sl@0
   691
	//[ set the volume on the device ]
sl@0
   692
	iMMFDevSound->SetVolume(aVolume);
sl@0
   693
sl@0
   694
	//[ assert the post condition volume is equal to a volume]
sl@0
   695
	TInt soundVolume = 0;
sl@0
   696
	soundVolume = iMMFDevSound->Volume();
sl@0
   697
sl@0
   698
    __ASSERT_ALWAYS( ( soundVolume == aVolume), Panic(EPostConditionViolation));
sl@0
   699
sl@0
   700
	//[ assert the invariant ]
sl@0
   701
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterVolumeSet));
sl@0
   702
	}
sl@0
   703
sl@0
   704
/**
sl@0
   705
Gets the maximum level the playback volume can be set to
sl@0
   706
sl@0
   707
@internalTechnology
sl@0
   708
@param aMaxVolume contains the maximum volume setting
sl@0
   709
*/
sl@0
   710
void CMMFAudioToneController::MapdGetMaxVolumeL(TInt& aMaxVolume)
sl@0
   711
	{
sl@0
   712
	// [ assert the invariant ]
sl@0
   713
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetMaxVolume));
sl@0
   714
sl@0
   715
	//[ precondition we have a data sink ]
sl@0
   716
	if (!iMMFDevSound)
sl@0
   717
		User::Leave(KErrNotReady);
sl@0
   718
sl@0
   719
	//[ get the volume from the device ]
sl@0
   720
	aMaxVolume = iMMFDevSound->MaxVolume();
sl@0
   721
sl@0
   722
	//[ assert the invariant ]
sl@0
   723
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetMaxVolume));
sl@0
   724
sl@0
   725
	}
sl@0
   726
sl@0
   727
sl@0
   728
/**
sl@0
   729
Gets the current playback volume
sl@0
   730
sl@0
   731
@internalTechnology
sl@0
   732
@param aVolume the current volume
sl@0
   733
*/
sl@0
   734
void CMMFAudioToneController::MapdGetVolumeL(TInt& aVolume)
sl@0
   735
	{
sl@0
   736
	// [ assert the invariant ]
sl@0
   737
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetVolume));
sl@0
   738
sl@0
   739
	//[  precondition that we have a data sink ]
sl@0
   740
	if (!iMMFDevSound)
sl@0
   741
		User::Leave(KErrNotReady);
sl@0
   742
sl@0
   743
	aVolume = iMMFDevSound->Volume();
sl@0
   744
	
sl@0
   745
	// [ assert precondition that the volume is in range
sl@0
   746
	//     0.. aMaxVolume ]
sl@0
   747
	TInt aMaxVolume = iMMFDevSound->MaxVolume();
sl@0
   748
	__ASSERT_ALWAYS( (aVolume <= aMaxVolume), Panic(EBadState));
sl@0
   749
	__ASSERT_ALWAYS( (aVolume >= 0), Panic(EBadState));
sl@0
   750
sl@0
   751
	// [ assert the invariant ]
sl@0
   752
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetVolume));
sl@0
   753
sl@0
   754
	}
sl@0
   755
sl@0
   756
/**
sl@0
   757
Sets the duration over which the volume should increase
sl@0
   758
sl@0
   759
@internalTechnology
sl@0
   760
@param aRampDuration the time over which the volume should ramp
sl@0
   761
*/
sl@0
   762
void CMMFAudioToneController::MapdSetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration)
sl@0
   763
	{
sl@0
   764
     // [ assert the invariant ]
sl@0
   765
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetVolumeRamp));
sl@0
   766
sl@0
   767
	//[ precondition that we have a data sink ]
sl@0
   768
	if (!iMMFDevSound)
sl@0
   769
		User::Leave(KErrNotReady);
sl@0
   770
sl@0
   771
	iMMFDevSound->SetVolumeRamp(aRampDuration);
sl@0
   772
	
sl@0
   773
	//[ assert the invariant ]
sl@0
   774
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterSetVolumeRamp));
sl@0
   775
		
sl@0
   776
	}
sl@0
   777
sl@0
   778
sl@0
   779
/**
sl@0
   780
Sets the balance of the tone playback
sl@0
   781
sl@0
   782
@internalTechnology
sl@0
   783
@param aBalance the required balance level (KMMFBalanceMaxLeft <= aBalance <= KMMFBalanceMaxRight)
sl@0
   784
*/
sl@0
   785
void CMMFAudioToneController::MapdSetBalanceL(TInt aBalance)
sl@0
   786
	{
sl@0
   787
	//[ assert the invariant ]
sl@0
   788
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateToSetBalance));
sl@0
   789
sl@0
   790
	// [ precondition is that we have a data sink ]
sl@0
   791
	if (!iMMFDevSound)
sl@0
   792
		User::Leave(KErrNotReady);
sl@0
   793
	
sl@0
   794
	
sl@0
   795
	// [ separate out left and right balance ]
sl@0
   796
	TInt left  = 0;
sl@0
   797
	TInt right = 0;
sl@0
   798
	CalculateLeftRightBalance( left, right, aBalance );
sl@0
   799
	
sl@0
   800
	//[ set the balance ]
sl@0
   801
	iMMFDevSound->SetPlayBalanceL(left, right); 
sl@0
   802
sl@0
   803
	// [assert the post condition that the balance is set correctly]
sl@0
   804
	TInt rightBalance = 0;
sl@0
   805
	TInt leftBalance  = 0;
sl@0
   806
	iMMFDevSound->GetPlayBalanceL(leftBalance, rightBalance); 
sl@0
   807
sl@0
   808
	//[ assert post condition holds]
sl@0
   809
	TBool postCondition = (( rightBalance == right) && ( leftBalance == left));
sl@0
   810
	__ASSERT_ALWAYS( postCondition, Panic( EPostConditionViolation ) );
sl@0
   811
sl@0
   812
	//[ assert the invariant ]
sl@0
   813
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateAfterSetBalance));
sl@0
   814
	}
sl@0
   815
sl@0
   816
/**
sl@0
   817
Converts the balance from a range to a left/right form.
sl@0
   818
sl@0
   819
Balance is provided to devsound using left and right levels, but supplied to the controller as a range 
sl@0
   820
(KMMFBalanceMaxLeft --> KMMFBalanceMaxRight). This method converts the range into a left/right form
sl@0
   821
sl@0
   822
@internalComponent
sl@0
   823
sl@0
   824
@param aLeft set to the left setting
sl@0
   825
@param aRight set to the right setting
sl@0
   826
@param aBalance the range required
sl@0
   827
*/
sl@0
   828
void CMMFAudioToneController::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
sl@0
   829
	{
sl@0
   830
	// Check the balance is within limits & modify to min or max values if necessary
sl@0
   831
	if (aBalance < KMMFBalanceMaxLeft)
sl@0
   832
		aBalance = KMMFBalanceMaxLeft;
sl@0
   833
	if (aBalance > KMMFBalanceMaxRight)
sl@0
   834
		aBalance = KMMFBalanceMaxRight;
sl@0
   835
	
sl@0
   836
	//[ Now separate percentage balances out from aBalance ]
sl@0
   837
	 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
sl@0
   838
     aRight = 100 - aLeft;
sl@0
   839
sl@0
   840
	 //[ assert post condition that left and right are within range ]
sl@0
   841
	 __ASSERT_ALWAYS( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPostConditionViolation));
sl@0
   842
	 __ASSERT_ALWAYS( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPostConditionViolation));
sl@0
   843
	}
sl@0
   844
sl@0
   845
sl@0
   846
/**
sl@0
   847
Gets the balance of the tone playback
sl@0
   848
sl@0
   849
@internalTechnology
sl@0
   850
@param aBalance set to the current balance level (KMMFBalanceMaxLeft <= aBalance <= KMMFBalanceMaxRight)
sl@0
   851
*/
sl@0
   852
void CMMFAudioToneController::MapdGetBalanceL(TInt& aBalance)
sl@0
   853
	{
sl@0
   854
	//[ assert the invariant ]
sl@0
   855
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetBalance));
sl@0
   856
sl@0
   857
	//[ precondition that we have a sink]
sl@0
   858
	if (!iMMFDevSound)
sl@0
   859
		User::Leave(KErrNotReady);
sl@0
   860
	
sl@0
   861
	
sl@0
   862
	TInt left = 50; // arbitrary values 
sl@0
   863
	TInt right = 50;
sl@0
   864
	iMMFDevSound->GetPlayBalanceL(left, right); 
sl@0
   865
sl@0
   866
    CalculateBalance( aBalance, left, right );
sl@0
   867
sl@0
   868
	//[ assert the invariant ]
sl@0
   869
	__ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetBalance));
sl@0
   870
	}
sl@0
   871
sl@0
   872
sl@0
   873
/**
sl@0
   874
Converts the balance from a left/right form to a range.
sl@0
   875
sl@0
   876
Balance is obtained from  DevSound using left and right levels, but supplied to the client as a range 
sl@0
   877
(KMMFBalanceMaxLeft --> KMMFBalanceMaxRight).
sl@0
   878
sl@0
   879
@internalComponent
sl@0
   880
sl@0
   881
@param aLeft the current left setting
sl@0
   882
@param aRight current right setting
sl@0
   883
@param aBalance set to the balance range
sl@0
   884
*/
sl@0
   885
void CMMFAudioToneController::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
sl@0
   886
	{
sl@0
   887
	//[ assert pre conditions ]
sl@0
   888
	__ASSERT_ALWAYS( (( aLeft + aRight ) == 100 ), Panic( EBadArgument ));
sl@0
   889
	__ASSERT_ALWAYS( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EBadArgument) );
sl@0
   890
	__ASSERT_ALWAYS( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EBadArgument) );
sl@0
   891
sl@0
   892
	aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
sl@0
   893
sl@0
   894
    //[ assert post condition that aBalance is within limits ]
sl@0
   895
	__ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
sl@0
   896
	
sl@0
   897
	}
sl@0
   898
sl@0
   899
sl@0
   900
sl@0
   901
sl@0
   902
/**
sl@0
   903
The function validates a state transition from iState to aState and 
sl@0
   904
returns ETrue if the transition is allowed.
sl@0
   905
sl@0
   906
@internalComponent
sl@0
   907
@param TControllerState
sl@0
   908
@return Valid controller state or not 
sl@0
   909
*/
sl@0
   910
TBool CMMFAudioToneController::IsValidStateTransition( TControllerState aState ) const
sl@0
   911
	{
sl@0
   912
	 TBool result = ETrue ;
sl@0
   913
	//[ assert the precondition that aState is a valid State ]
sl@0
   914
	__ASSERT_ALWAYS( IsValidState(aState), Panic( EBadArgument ) );
sl@0
   915
	//[ assert the invariant that iState is a valid State ]
sl@0
   916
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateForTransition ));
sl@0
   917
sl@0
   918
	// [ check the valid state transitions ]
sl@0
   919
	  // the only invalid transition is
sl@0
   920
	  // stopped to playing
sl@0
   921
	if( ( iState == EStopped ) && ( aState == EPlaying ))
sl@0
   922
		{
sl@0
   923
         result = EFalse ;
sl@0
   924
		}
sl@0
   925
  
sl@0
   926
	//[ assert the invariant that iState is a valid State ]
sl@0
   927
	__ASSERT_ALWAYS( Invariant(), Panic( EBadStateAfterTransition ));
sl@0
   928
sl@0
   929
	return result ;
sl@0
   930
	}
sl@0
   931
sl@0
   932
/*
sl@0
   933
This function returns whether the invariant is valid
sl@0
   934
sl@0
   935
@internalComponent
sl@0
   936
@return Is the class in a good condition
sl@0
   937
*/
sl@0
   938
TBool  CMMFAudioToneController::Invariant() const
sl@0
   939
	{
sl@0
   940
	//[ The invariant is for now defined 
sl@0
   941
	// as simply being in the correct state
sl@0
   942
	return IsValidState( iState);
sl@0
   943
	}
sl@0
   944
sl@0
   945
/*
sl@0
   946
This function sets the state of the controller.
sl@0
   947
sl@0
   948
@internalComponent
sl@0
   949
@return Whether ths state transition is valid
sl@0
   950
*/
sl@0
   951
TBool CMMFAudioToneController::SetState(TControllerState aState)
sl@0
   952
	{
sl@0
   953
	TBool result = ETrue;
sl@0
   954
	//[ assert the precondition that the state is a valid state ]
sl@0
   955
   	__ASSERT_ALWAYS( IsValidState( aState),  Panic( EBadArgument ) );
sl@0
   956
	//[ assert the invariant the current state is valid ]
sl@0
   957
	__ASSERT_ALWAYS( Invariant(),  Panic( EStateNotValid ) );
sl@0
   958
    //[ only allow valid state transitions ]
sl@0
   959
	if( IsValidStateTransition( aState ) )	
sl@0
   960
		{
sl@0
   961
		//[ valid state transition set the state]
sl@0
   962
		iState = aState ;
sl@0
   963
		}
sl@0
   964
	else
sl@0
   965
		{
sl@0
   966
		//[ invalid state transition return EFalse ]
sl@0
   967
		result = EFalse;         
sl@0
   968
		}
sl@0
   969
	// [ assert the invariant on the state ]
sl@0
   970
	__ASSERT_ALWAYS( Invariant(), Panic( EBadState ));
sl@0
   971
	
sl@0
   972
	return result ;
sl@0
   973
	}
sl@0
   974
sl@0
   975
/*
sl@0
   976
checks whether a state is valid 
sl@0
   977
sl@0
   978
@internalComponent
sl@0
   979
@return Is the state a valid one
sl@0
   980
*/
sl@0
   981
TBool  CMMFAudioToneController::IsValidState( TControllerState aState ) const 
sl@0
   982
	{
sl@0
   983
	TBool result = EFalse;
sl@0
   984
     if(( aState >= EStopped ) && ( aState <= EPlaying ))
sl@0
   985
		 {
sl@0
   986
          result = ETrue;
sl@0
   987
		 }
sl@0
   988
	 return result;
sl@0
   989
	}
sl@0
   990
sl@0
   991
/**
sl@0
   992
The function State returns the current state of the audio controller
sl@0
   993
sl@0
   994
@internalComponent
sl@0
   995
@return State of the controller
sl@0
   996
*/
sl@0
   997
CMMFAudioToneController::TControllerState CMMFAudioToneController::State() const
sl@0
   998
	{
sl@0
   999
	__ASSERT_ALWAYS( Invariant(), Panic( EBadState ) );
sl@0
  1000
	return iState;
sl@0
  1001
	}
sl@0
  1002
sl@0
  1003
sl@0
  1004
/**
sl@0
  1005
* MapcSetRepeatsL
sl@0
  1006
* @param aRepeatNumberOfTimes
sl@0
  1007
* @param aTrailingSilence
sl@0
  1008
*
sl@0
  1009
*/
sl@0
  1010
TInt CMMFAudioToneController::MapcSetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
sl@0
  1011
	{
sl@0
  1012
	TInt err = KErrNone;
sl@0
  1013
	if (!iMMFDevSound)
sl@0
  1014
		{
sl@0
  1015
		return KErrNotReady;
sl@0
  1016
		}		
sl@0
  1017
	else
sl@0
  1018
		{
sl@0
  1019
		if(iMMFDevSound->QueryIgnoresUnderflow())
sl@0
  1020
			{
sl@0
  1021
			iMMFDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence);
sl@0
  1022
			}
sl@0
  1023
		else
sl@0
  1024
			{
sl@0
  1025
			err = KErrNotSupported;
sl@0
  1026
			}
sl@0
  1027
		}
sl@0
  1028
	return err;
sl@0
  1029
	}