os/mm/mmlibs/mmfw/src/Client/Audio/mmfclienttoneplayer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <mmf/common/mmfpaniccodes.h>
    17 
    18 #include "mmfclienttoneplayer.h"
    19 using namespace ContentAccess;
    20 enum TMmfMdaAudioToneUtility
    21 	{
    22 	EBadArgument,
    23 	EPostConditionViolation, 
    24 	EPlayStartedCalledWithError
    25 	};
    26 
    27 // declared in the recorder module
    28 void Panic(TInt aPanicCode);
    29 
    30 /**
    31 Creates a new instance of the tone player utility.
    32 The default  volume is set to MaxVolume() / 2.
    33 
    34 @param  aObserver
    35         A class to receive notifications from the tone player.
    36 @param  aServer
    37         This parameter is no longer used and should be NULL.
    38 
    39 @return A pointer to the new audio tone player utility object.
    40 
    41 @since 5.0
    42 */
    43 EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* aServer /*= NULL*/)
    44 	{
    45 	return CMdaAudioToneUtility::NewL(aObserver, aServer, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
    46 	}
    47 
    48 /**
    49 Creates a new instance of the tone player utility.
    50 The default  volume is set to MaxVolume() / 2.
    51 
    52 @param  aObserver
    53         A class to receive notifications from the tone player
    54 @param  aServer
    55         This parameter is no longer used and should be NULL
    56 @param  aPriority
    57         The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and 
    58         EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
    59 @param  aPref
    60         The Priority Preference - an additional audio policy parameter. The suggested default is 
    61         EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional 
    62         values may be supported by given phones and/or platforms, but should not be depended upon by 
    63         portable code.
    64 
    65 @return A pointer to the new audio tone player utility object.
    66 
    67 @since 5.0
    68 
    69 Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
    70 several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, 
    71 the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. 
    72 Whatever, the decision  as to what to do in such situations is up to the audio adaptation, and may
    73 vary between different phones. Portable applications are advised not to assume any specific behaviour. 
    74 */
    75 EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
    76 														  TInt aPriority /*= EMdaPriorityNormal*/,
    77 														  TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
    78 	{
    79 	CMdaAudioToneUtility* self = new(ELeave) CMdaAudioToneUtility();
    80 	CleanupStack::PushL(self);
    81 	self->iProperties = CMMFMdaAudioToneUtility::NewL(aObserver, NULL, aPriority, aPref);
    82 	CleanupStack::Pop(); //self
    83 	return self;
    84 	}
    85 
    86 /**
    87 Destructor. Frees any resources held by the tone player
    88 
    89 @since 5.0
    90 */
    91 CMdaAudioToneUtility::~CMdaAudioToneUtility()
    92 	{
    93 	delete iProperties;
    94 	}
    95 
    96 /**
    97 Returns the current state of the audio tone utility.
    98 
    99 @return The state of the audio tone utility.
   100 
   101 @since  5.0
   102 */
   103 TMdaAudioToneUtilityState CMdaAudioToneUtility::State()
   104 	{
   105 	ASSERT(iProperties);
   106 	return iProperties->State();
   107 	}
   108 	
   109 /**
   110 Returns the maximum volume supported by the device. This is the maximum value which can be 
   111 passed to CMdaAudioToneUtility::SetVolume().
   112 
   113 @return The maximum volume. This value is platform dependent but is always greater than or equal to one.
   114 
   115 @since  5.0
   116 */
   117 TInt CMdaAudioToneUtility::MaxVolume()
   118 	{
   119 	ASSERT(iProperties);
   120 	return iProperties->MaxVolume();
   121 	}
   122 	
   123 /**
   124 Returns an integer representing the current volume of the audio device.
   125 
   126 @return The current volume.
   127 
   128 @since 		5.0
   129 */
   130 TInt CMdaAudioToneUtility::Volume()
   131 	{
   132 	ASSERT(iProperties);
   133 	return iProperties->Volume();
   134 	}
   135 	
   136 /**
   137 Changes the volume of the audio device.
   138 
   139 The volume can be changed before or during play and is effective
   140 immediately.
   141 
   142 @param  aVolume
   143         The volume setting. This can be any value from zero to
   144         the value returned by a call to
   145         CMdaAudioToneUtility::MaxVolume().
   146         Setting a zero value mutes the sound. Setting the
   147         maximum value results in the loudest possible sound.
   148 
   149 @since  5.0
   150 */
   151 void CMdaAudioToneUtility::SetVolume(TInt aVolume)
   152 	{
   153 	ASSERT(iProperties);
   154 	iProperties->SetVolume(aVolume);
   155 	}
   156 	
   157 /**
   158 Changes the clients priority.
   159 
   160 @param  aPriority
   161         The Priority Value.
   162 @param  aPref
   163         The Priority Preference.
   164 
   165 @see CMdaAudioToneUtility::NewL()
   166 
   167 @since  5.0
   168 
   169 */
   170 void CMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
   171 	{
   172 	ASSERT(iProperties);
   173 	iProperties->SetPriority(aPriority, aPref);
   174 	}
   175 
   176 /**
   177 Changes the duration of DTMF tones, the gaps between DTMF tones and the
   178 pauses.
   179 
   180 @param  aToneLength
   181         The duration of the DTMF tone in microseconds.
   182 @param  aToneOffLength
   183         The gap between DTFM tones in microseconds.
   184 @param  aPauseLength
   185         Pauses in microseconds
   186 */
   187 void CMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
   188 										  TTimeIntervalMicroSeconds32 aToneOffLength,
   189 										  TTimeIntervalMicroSeconds32 aPauseLength)
   190 	{
   191 	ASSERT(iProperties);
   192 	iProperties->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength);
   193 	}
   194 
   195 /**
   196 Sets the number of times the tone sequence is to be repeated during
   197 the play operation.
   198 
   199 A period of silence can follow each playing of the tone sequence. The
   200 tone sequence can be repeated indefinitely.
   201 
   202 @param  aRepeatNumberOfTimes
   203         The number of times the tone sequence, together with
   204         the trailing silence, is to be repeated. If this is
   205         set to KMdaRepeatForever, then the tone
   206         sequence, together with the trailing silence, is
   207         repeated indefinitely. The behaviour is undefined for values other than  
   208 		KMdaRepeatForever, zero and positive.
   209 @param  aTrailingSilence
   210         The time interval of the training silence. The behaviour is undefined
   211         for values other than zero and positive.
   212 
   213 @since  5.0
   214 */
   215 void CMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes,
   216 									  const TTimeIntervalMicroSeconds& aTrailingSilence)
   217 	{
   218 	ASSERT(iProperties);
   219 	iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
   220 	}
   221 
   222 /**
   223 Defines the period over which the volume level is to rise smoothly
   224 from nothing to the normal volume level.
   225 
   226 @param  aRampDuration
   227         The period over which the volume is to rise. A zero
   228         value causes the tone to be played at the normal level
   229         for the full duration of the playback. A value which
   230         is longer than the duration of the tone sequence means
   231         that the tone never reaches its normal volume level.
   232 
   233 @since  5.0
   234 */
   235 void CMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
   236 	{
   237 	ASSERT(iProperties);
   238 	iProperties->SetVolumeRamp(aRampDuration);
   239 	}
   240 
   241 /**
   242 Returns the number of available pre-defined tone sequences.
   243 
   244 @return The number of tone sequences. This value is implementation 
   245 		dependent but is always greater than or equal to zero.
   246 
   247 @since  5.0
   248 */
   249 TInt CMdaAudioToneUtility::FixedSequenceCount()
   250 	{
   251 	ASSERT(iProperties);
   252 	return iProperties->FixedSequenceCount();
   253 	}
   254 
   255 /**
   256 Returns the name assigned to a specific pre-defined tone sequence.
   257 
   258 @param  aSequenceNumber
   259         The index identifying the specific pre-defined tone sequence. 
   260         Index values are relative to zero. This can be any value from 
   261         zero to the value returned by a call to FixedSequenceCount() - 1.
   262         The function raises a panic if sequence number is not within this
   263  		range.
   264 
   265 @see CMMFDevSound::FixedSequenceName(TInt aSequenceNumber)
   266 @see FixedSequenceCount()
   267 
   268 @return The name assigned to the tone sequence.
   269 
   270 @since  5.0
   271 */
   272 const TDesC& CMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
   273 	{
   274 	ASSERT(iProperties);
   275 	return iProperties->FixedSequenceName(aSequenceNumber);
   276 	}
   277 
   278 /**
   279 Configures the audio tone player utility to play a single tone.
   280 
   281 This function is asynchronous. On completion, the observer callback
   282 function MMdaAudioToneObserver::MatoPrepareComplete() is
   283 called, indicating the success or failure of the configuration
   284 operation.The configuration operation can be cancelled by calling
   285 CMdaAudioToneUtility::CancelPrepare(). The configuration
   286 operation cannot be started if a play operation is in progress.
   287 
   288 @param     aFrequency
   289            The frequency (pitch) of the tone in Hz.
   290 @param     aDuration
   291            The duration of the tone in microseconds.
   292 @since     5.0
   293 */
   294 void CMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
   295 	{
   296 	ASSERT(iProperties);
   297 	iProperties->PrepareToPlayTone(aFrequency, aDuration);
   298 	}
   299 
   300 /**
   301 Configures the audio tone player utility to play a dual tone.
   302 The generated tone consists of two sine waves of different
   303 frequencies summed together.
   304 
   305 This function is asynchronous. On completion, the observer callback
   306 function MMdaAudioToneObserver::MatoPrepareComplete() is
   307 called, indicating the success or failure of the configuration
   308 operation. The configuration operation can be cancelled by calling
   309 CMdaAudioToneUtility::CancelPrepare(). The configuration
   310 operation cannot be started if a play operation is in progress.
   311 
   312 @param  aFrequencyOne
   313         The first frequency (pitch) of the tone.
   314 @param  aFrequencyTwo
   315         The second frequency (pitch) of the tone.
   316 @param  aDuration
   317         The duration of the tone in microseconds.
   318 
   319 @since  7.0sy
   320 */
   321 EXPORT_C void CMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
   322 	{
   323 	ASSERT(iProperties);
   324 	iProperties->PrepareToPlayDualTone(aFrequencyOne, aFrequencyTwo, aDuration);
   325 	}
   326 
   327 /**
   328 Configures the audio tone utility player to play a DTMF (Dual-Tone
   329 Multi-Frequency) string.
   330 
   331 This function is asynchronous. On completion, the observer callback
   332 function MMdaAudioToneObserver::MatoPrepareComplete() is
   333 called, indicating the success or failure of the configuration
   334 operation. The configuration operation can be cancelled by calling
   335 CMdaAudioToneUtility::CancelPrepare(). The configuration
   336 operation cannot be started if a play operation is in progress.
   337 
   338 @param  aDTMF
   339         A descriptor containing the DTMF string.
   340 
   341 @since  5.0
   342 */
   343 void CMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
   344 	{
   345 	ASSERT(iProperties);
   346 	iProperties->PrepareToPlayDTMFString(aDTMF);
   347 	}
   348 
   349 /**
   350 Configures the audio tone player utility to play a tone sequence
   351 contained in a descriptor.
   352 
   353 This function is asynchronous. On completion, the observer callback
   354 function MMdaAudioToneObserver::MatoPrepareComplete() is
   355 called, indicating the success or failure of the configuration
   356 operation. The configuration operation can be cancelled by calling
   357 CMdaAudioToneUtility::CancelPrepare(). The configuration
   358 operation cannot be started if a play operation is in progress.
   359 
   360 @param  aSequence
   361         The descriptor containing the tone sequence. The
   362         format of the data is unspecified but is expected to
   363         be platform dependent. A device might support more
   364         than one form of sequence data.
   365 
   366 @since  5.0
   367 */
   368 void CMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
   369 	{
   370 	ASSERT(iProperties);
   371 	iProperties->PrepareToPlayDesSequence(aSequence);
   372 	}
   373 
   374 /**
   375 Configures the audio tone player utility to play a tone sequence
   376 contained in a file.
   377 
   378 This function is asynchronous. On completion, the observer callback
   379 function MMdaAudioToneObserver::MatoPrepareComplete() is
   380 called, indicating the success or failure of the configuration
   381 operation. The configuration operation can be cancelled by calling
   382 CMdaAudioToneUtility::CancelPrepare(). The configuration
   383 operation cannot be started if a play operation is in progress.
   384 
   385 @param  aFileName
   386         The full path name of the file containing the tone
   387         sequence. The format of the data is unspecified but is
   388         expected to be platform dependent. A device might
   389         support more than one form of sequence data.
   390 
   391 @since  5.0
   392 */
   393 void CMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
   394 	{
   395 	ASSERT(iProperties);
   396 	iProperties->PrepareToPlayFileSequence(aFileName);
   397 	}
   398 	
   399 /**
   400 Configures the audio tone player utility to play a tone sequence
   401 contained in a file.
   402 
   403 This function is asynchronous. On completion, the observer callback
   404 function MMdaAudioToneObserver::MatoPrepareComplete() is
   405 called, indicating the success or failure of the configuration
   406 operation. The configuration operation can be cancelled by calling
   407 CMdaAudioToneUtility::CancelPrepare(). The configuration
   408 operation cannot be started if a play operation is in progress.
   409 
   410 @param  aFile
   411         A handle to an open file containing the tone
   412         sequence. The format of the data is unspecified but is
   413         expected to be platform dependent. A device might
   414         support more than one form of sequence data.
   415 
   416 @since  5.0
   417 */
   418 EXPORT_C void CMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFile)
   419 	{
   420 	ASSERT(iProperties);
   421 	iProperties->PrepareToPlayFileSequence(aFile);
   422 	}
   423 	
   424 
   425 /**
   426 Configures the audio tone player utility to play the specified
   427 pre-defined tone sequence.
   428 
   429 This function is asynchronous. On completion, the observer callback
   430 function MMdaAudioToneObserver::MatoPrepareComplete() is
   431 called, indicating the success or failure of the configuration
   432 operation. The configuration operation can be cancelled by calling
   433 CMdaAudioToneUtility::CancelPrepare(). The configuration
   434 operation cannot be started if a play operation is in progress.
   435 
   436 @param  aSequenceNumber
   437         An index into the set of pre-defined tone sequences.
   438         This can be any value from zero to the value returned by a 
   439         call to FixedSequenceCount() - 1.
   440         If the sequence number is not within this range, a panic will be 
   441         raised when Play() is called later.
   442 
   443 @see FixedSequenceCount()
   444 @see CMMFDevSound::PlayFixedSequenceL(TInt aSequenceNumber)
   445 
   446 @since  5.0
   447 */
   448 void CMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
   449 	{
   450 	ASSERT(iProperties);
   451 	iProperties->PrepareToPlayFixedSequence(aSequenceNumber);
   452 	}
   453 
   454 /**
   455 Cancels the configuration operation.
   456 
   457 The observer callback function
   458 MMdaAudioToneObserver::MatoPrepareComplete() is not
   459 called.
   460 
   461 @since  5.0
   462 */
   463 void CMdaAudioToneUtility::CancelPrepare()
   464 	{
   465 	ASSERT(iProperties);
   466 	iProperties->CancelPrepare();
   467 	}
   468 
   469 /**
   470 Plays the tone.
   471 
   472 The tone played depends on the current configuration.This function is
   473 asynchronous. On completion, the observer callback function
   474 MMdaAudioToneObserver::MatoPlayComplete() is called,
   475 indicating the success or failure of the play operation.The play
   476 operation can be cancelled by
   477 calling CMdaAudioToneUtility::CancelPlay().
   478 
   479 @since  5.0
   480 */
   481 void CMdaAudioToneUtility::Play()
   482 	{
   483 	ASSERT(iProperties);
   484 	iProperties->Play();
   485 	}
   486 
   487 EXPORT_C TInt CMdaAudioToneUtility::Pause()
   488 	{
   489 	ASSERT(iProperties);
   490 	return iProperties->Pause();
   491 	}
   492 
   493 EXPORT_C TInt CMdaAudioToneUtility::Resume()
   494 	{
   495 	ASSERT(iProperties);
   496 	return iProperties->Resume();
   497 	}
   498 
   499 /**
   500 Cancels the tone playing operation.
   501 
   502 The observer callback
   503 function MMdaAudioToneObserver::MatoPlayComplete() is not
   504 called.
   505 
   506 @since  5.0
   507 */
   508 void CMdaAudioToneUtility::CancelPlay()
   509 	{
   510 	ASSERT(iProperties);
   511 	iProperties->CancelPlay();
   512 	}
   513 
   514 /**
   515 Sets the stereo balance for playback.
   516 
   517 @param 	aBalance
   518         The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
   519 
   520 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
   521         another of the system-wide error codes.
   522 
   523 @since 7.0s
   524 */
   525 EXPORT_C void CMdaAudioToneUtility::SetBalanceL(TInt aBalance /*=KMMFBalanceCenter*/)
   526 	{
   527 	ASSERT(iProperties);
   528 	iProperties->SetBalanceL(aBalance);
   529 	}
   530 
   531 /**
   532  *	Returns The current playback balance.This function may not return the same value 
   533  *			as passed to SetBalanceL depending on the internal implementation in 
   534  *			the underlying components.
   535  *
   536  *	@return The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
   537  *		
   538  *  @since 	7.0s
   539  */
   540 EXPORT_C TInt CMdaAudioToneUtility::GetBalanceL()
   541 	{
   542 	ASSERT(iProperties);
   543 	return iProperties->GetBalanceL();
   544 	}
   545 	
   546 /**
   547 Retrieves a custom interface to the underlying device.
   548 
   549 @param  aInterfaceId
   550         The interface UID, defined with the custom interface.
   551 
   552 @return A pointer to the interface implementation, or NULL if the device does not
   553         implement the interface requested. The return value must be cast to the
   554         correct type by the user.
   555 */
   556 EXPORT_C TAny* CMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
   557 	{
   558 	ASSERT(iProperties);
   559 	return iProperties->CustomInterface(aInterfaceId);
   560 	}
   561 
   562 EXPORT_C void CMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
   563 	{
   564 	ASSERT(iProperties);
   565 	iProperties->RegisterPlayStartCallback(aObserver);
   566 	}
   567 
   568 
   569 
   570 CMMFMdaAudioToneUtility* CMMFMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
   571 														  TInt aPriority /*= EMdaPriorityNormal*/, 
   572 														  TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
   573 														  
   574 	{
   575 	CMMFMdaAudioToneUtility* self = new(ELeave) CMMFMdaAudioToneUtility(aObserver, aPriority, aPref);
   576 	CleanupStack::PushL(self);
   577 	self->ConstructL();
   578 	CleanupStack::Pop(self);
   579 	return self;
   580 	}
   581 
   582 
   583 
   584 CMMFMdaAudioToneUtility::CMMFMdaAudioToneUtility(MMdaAudioToneObserver& aCallback, TInt aPriority, TInt aPref) :
   585 	iCallback(aCallback)
   586 	{
   587 	iPrioritySettings.iPref = aPref;
   588 	iPrioritySettings.iPriority = aPriority;
   589 	iState = EMdaAudioToneUtilityNotReady;
   590 	iInitialized = EFalse;
   591 	iPlayCalled = EFalse;
   592 
   593 #ifdef _DEBUG
   594 	iPlayCalledBeforeInitialized = EFalse;
   595 #endif
   596 	}
   597 
   598 void CMMFMdaAudioToneUtility::ConstructL()
   599 	{
   600 	iAsyncCallback = CMMFMdaAudioToneObserverCallback::NewL(*this, *this);
   601 
   602 	iDevSound = CMMFDevSound::NewL();
   603 	iDevSound->InitializeL(*this,EMMFStateTonePlaying);
   604 	
   605 	// In some implementations InitializeComplete() returns in the InitializeL() context,
   606 	// check the error
   607 	User::LeaveIfError(iInitializeState);
   608 
   609 	iDevSound->SetPrioritySettings(iPrioritySettings);
   610 	SetVolume(MaxVolume()/2 ); // set the volume to an intermediate value 
   611 	}
   612 
   613 CMMFMdaAudioToneUtility::~CMMFMdaAudioToneUtility()
   614 	{
   615 	delete iDevSound;
   616 	delete iAsyncCallback;
   617 	delete iToneConfig;
   618 	}
   619 
   620 
   621 
   622 void CMMFMdaAudioToneUtility::InitializeComplete(TInt aError)
   623 	{
   624 #ifdef _DEBUG
   625 	__ASSERT_ALWAYS(!iPlayCalledBeforeInitialized, User::Panic(_L("PlayInitialized called before InitializeComplete"), 0));
   626 #endif
   627 	iInitialized = ETrue;
   628 
   629 	if (iPlayCalled)
   630 		{
   631 		// Play() is called before InitializeComplete()
   632 		if (aError == KErrNone)
   633 			{
   634 			PlayAfterInitialized();
   635  			}
   636  		else 
   637  			{
   638  			// InitializeComplete() with error other than KErrNone
   639 			iState = EMdaAudioToneUtilityNotReady;
   640 			iAsyncCallback->MatoPlayComplete(aError);
   641  			}
   642  		iPlayCalled = EFalse;
   643 		}
   644  	iInitializeState = aError;
   645 	}
   646 
   647 void CMMFMdaAudioToneUtility::ToneFinished(TInt aError)
   648 	{
   649 	if (aError != KErrCancel)
   650 		{
   651 		if (aError == KErrUnderflow)
   652 			{
   653 			aError = KErrNone;
   654 			}
   655 
   656 		iAsyncCallback->MatoPlayComplete(aError);
   657 		}
   658 	// else don't want to callback after a cancel
   659 	}
   660 
   661 
   662 TMdaAudioToneUtilityState CMMFMdaAudioToneUtility::State()
   663 	{
   664 	return iState;
   665 	}
   666 
   667 TInt CMMFMdaAudioToneUtility::MaxVolume()
   668 	{
   669 	return iDevSound->MaxVolume();
   670 	}
   671 
   672 TInt CMMFMdaAudioToneUtility::Volume()
   673 	{
   674 	return iDevSound->Volume();
   675 	}
   676 
   677 void CMMFMdaAudioToneUtility::SetVolume(TInt aVolume) 
   678 	{
   679 	iDevSound->SetVolume(aVolume);
   680 	}
   681 
   682 void CMMFMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
   683 	{
   684 	iPrioritySettings.iPref = aPref;
   685 	iPrioritySettings.iPriority = aPriority;
   686 	iDevSound->SetPrioritySettings(iPrioritySettings);
   687 	}
   688 
   689 void CMMFMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength, 
   690 										 TTimeIntervalMicroSeconds32 aToneOffLength,
   691 										 TTimeIntervalMicroSeconds32 aPauseLength)
   692 	{
   693 	iDevSound->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength);
   694 	}
   695 
   696 void CMMFMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
   697 	{
   698 	iDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence);
   699 	}
   700 
   701 void CMMFMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
   702 	{
   703 	iDevSound->SetVolumeRamp(aRampDuration);
   704 	}
   705 
   706 TInt CMMFMdaAudioToneUtility::FixedSequenceCount()
   707 	{
   708 	return iDevSound->FixedSequenceCount();
   709 	}
   710 
   711 const TDesC& CMMFMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
   712 	{
   713 	return iDevSound->FixedSequenceName(aSequenceNumber);
   714 	}
   715 
   716 /**
   717 * CalculateBalance
   718 * @param aBalance
   719 * @param aLeft
   720 * @param aRight
   721 *
   722 * follows a simple straight line transformation
   723 * y = m x + c
   724 * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100 
   725 * c = KMMFBalanceMaxRight
   726 * by substitution
   727 * when aLeft = 0
   728 *   KMMFBalanceMaxRight = m * 0 + c
   729 *   c = KMMFBalanceMaxRight
   730 * when aLeft = 100
   731 * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight
   732 * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100
   733 */
   734 void CMMFMdaAudioToneUtility::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
   735 	{
   736 	//[ assert pre conditions ]
   737 	__ASSERT_ALWAYS( (( aLeft + aRight ) == 100 ), Panic( EBadArgument ));
   738 	__ASSERT_ALWAYS( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EBadArgument) );
   739 	__ASSERT_ALWAYS( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EBadArgument) );
   740 
   741 	aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
   742 
   743     //[ assert post condition that aBalance is within limits ]
   744 	__ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
   745 	
   746 	}
   747 
   748 
   749 /**
   750 * CalculateLeftRightBalance
   751 * @param aLeft
   752 * @param aRight
   753 * @param aBalance
   754 * Preconditions:
   755 * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight)
   756 * y = m x + c
   757 * aLeft = m ( aBalance ) + c
   758 * when aBalance = KMMFBalanceMaxLeft   aLeft = 100
   759 * when aBalance = KMMFBalanceMaxRight  aLeft = 0
   760 * 100 = m( KMMFBalanceMaxLeft ) + c
   761 * 0   = m( KMMFBalanceMaxRight ) + c 
   762 * c = -(KMMFBalanceMaxRight) m
   763 * 100 = m(KMMFBalanceMaxLeft ) - m(KMMFBalanceMaxRight)
   764 * m = 100/(KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
   765 * c = -(KMMFBalanceMaxRight) * 100 /(KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
   766 * aLeft = ( aBalance - KMMFBalanceMaxRight ) * 100 /( KMMFBalanceMaxLeft - KMMFBalanceMaxRight )
   767 */
   768 void CMMFMdaAudioToneUtility::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
   769 	{
   770 	// [ assert precondition that aBalance is within limits ]
   771     __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
   772 	
   773 	//[ Now separate percentage balances out from aBalance ]
   774 	 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
   775      aRight = 100 - aLeft;
   776 
   777 	 //[ assert post condition that left and right are within range ]
   778 	 __ASSERT_ALWAYS( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPostConditionViolation));
   779 	 __ASSERT_ALWAYS( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPostConditionViolation));
   780 	}
   781 
   782 
   783 void CMMFMdaAudioToneUtility::SetBalanceL(TInt aBalance) 
   784 	{
   785 	TInt left;
   786 	TInt right;
   787 	CalculateLeftRightBalance(left,right,aBalance);
   788 	iDevSound->SetPlayBalanceL(left,right);
   789 	}
   790 
   791 TInt CMMFMdaAudioToneUtility::GetBalanceL() 
   792 	{
   793 	TInt left;
   794 	TInt right;
   795 	TInt balance;
   796 	iDevSound->GetPlayBalanceL(left, right);
   797 	CalculateBalance(balance,left,right);
   798 	return balance; 
   799 	}
   800 
   801 void CMMFMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
   802 	{
   803 	delete iToneConfig;
   804 	iToneConfig = NULL;
   805 	TRAPD(error, iToneConfig = CMMFSimpleToneConfig::NewL(aFrequency, aDuration));
   806 	iAsyncCallback->MatoPrepareComplete(error);
   807 	}
   808 
   809 void CMMFMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
   810 	{
   811 	delete iToneConfig; 
   812 	iToneConfig = NULL;
   813 	TRAPD(error, iToneConfig = CMMFDualToneConfig::NewL(aFrequencyOne, aFrequencyTwo, aDuration));
   814 	iAsyncCallback->MatoPrepareComplete(error);
   815 	}
   816 
   817 void CMMFMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
   818 	{
   819 	delete iToneConfig;
   820 	iToneConfig = NULL;
   821 	TRAPD(error, iToneConfig = CMMFDTMFStringToneConfig::NewL(aDTMF));
   822 	iAsyncCallback->MatoPrepareComplete(error);
   823 	}
   824 
   825 void CMMFMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
   826 	{
   827 	delete iToneConfig;
   828 	iToneConfig = NULL;
   829 	TRAPD(error, iToneConfig = CMMFDesSeqToneConfig::NewL(aSequence));
   830 	iAsyncCallback->MatoPrepareComplete(error);
   831 	}
   832 
   833 void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
   834 	{
   835 	delete iToneConfig;
   836 	iToneConfig = NULL;
   837 	TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName));
   838 	iAsyncCallback->MatoPrepareComplete(error);
   839 	}
   840 	
   841 void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFileName)
   842 	{
   843 	delete iToneConfig;
   844 	iToneConfig = NULL;
   845 	TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName));
   846 	iAsyncCallback->MatoPrepareComplete(error);
   847 	}
   848 
   849 
   850 
   851 
   852 void CMMFMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
   853 	{
   854 	delete iToneConfig;
   855 	iToneConfig = NULL;
   856 	TRAPD(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(aSequenceNumber));
   857 	iSequenceNumber = aSequenceNumber;
   858 	iAsyncCallback->MatoPrepareComplete(error);
   859 	}
   860 
   861 void CMMFMdaAudioToneUtility::CancelPrepare()
   862 	{
   863 	// xxx - do we need to cancel the callback?  What if the callback is actually calling back another error?  Probably best not to cancel...
   864 	delete iToneConfig;
   865 	iToneConfig = NULL;
   866 
   867 	if (iState == EMdaAudioToneUtilityPrepared)
   868 		{
   869 		iState = EMdaAudioToneUtilityNotReady;
   870 		}
   871 	// Cancel the AO
   872 	iAsyncCallback->Cancel();
   873 	}
   874 
   875 TInt CMMFMdaAudioToneUtility::Pause()
   876 	{
   877 	// Handle scenario when Pause is called before playback has started
   878 	if (iState != EMdaAudioToneUtilityPlaying || (iState == EMdaAudioToneUtilityPlaying && !iInitialized))
   879 		{
   880 		return KErrNotReady;
   881 		}
   882 
   883 	else if(! iDevSound->IsResumeSupported() || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq)
   884 		{
   885 		return KErrNotSupported;
   886 		}
   887 		
   888 	iDevSound->Pause();
   889 	iState = EMdaAudioToneUtilityPaused;
   890 	return KErrNone;
   891 	}
   892 
   893 TInt CMMFMdaAudioToneUtility::Resume()
   894 	{
   895 	TInt err = KErrNone;
   896 	if (iState != EMdaAudioToneUtilityPaused)
   897 		{
   898 		err = KErrNotReady;
   899 		}
   900 
   901 	else if( iDevSound->IsResumeSupported() == EFalse || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq)
   902 		{
   903 		err = KErrNotSupported;
   904 		}
   905 		
   906 	if(err == KErrNone)
   907 		{
   908 		err =  iDevSound->Resume();
   909 		if(err == KErrNone)
   910 			{
   911 			iState = EMdaAudioToneUtilityPlaying;
   912 			}
   913 		}
   914 	return err;
   915 	}
   916 
   917 void CMMFMdaAudioToneUtility::Play()
   918 	{
   919 	TInt error = KErrNone;
   920 
   921 	if ((iState == EMdaAudioToneUtilityPlaying) || (iState == EMdaAudioToneUtilityPaused) || iPlayCalled)
   922 		{
   923 		error = KErrInUse;
   924 		}
   925 			
   926 	if (!error)
   927 		{
   928 		if (!iToneConfig)
   929 			{
   930 			TRAP(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(iSequenceNumber));
   931 			}
   932 		}
   933 	// If there was an error, notify the client now.  Otherwise, client will be notified when
   934 	// play has finished.
   935 	if (error)
   936 		{
   937 		iState = EMdaAudioToneUtilityNotReady;
   938 		iAsyncCallback->MatoPlayComplete(error);
   939 		}
   940 			
   941 	if (!error)
   942 		{
   943 		iState = EMdaAudioToneUtilityPlaying;
   944 
   945 		if (iInitialized)
   946 			{
   947 			// Play() is called after InitializeComplete()
   948 			if (iInitializeState)
   949 				{
   950 				// InitializeComplete() with error other than KErrNone
   951 				iState = EMdaAudioToneUtilityNotReady;
   952 				iAsyncCallback->MatoPlayComplete(iInitializeState);
   953 				}
   954 			else
   955 				{
   956 				PlayAfterInitialized();
   957 				}
   958 			}
   959 		else
   960 			{
   961 			// Play() is called before InitializeComplete()
   962 			iPlayCalled = ETrue;
   963 			}
   964 		}
   965 	}
   966 
   967 void CMMFMdaAudioToneUtility::PlayAfterInitialized()
   968 	{
   969 #ifdef _DEBUG
   970 	if (iInitialized == EFalse)
   971 		{
   972 		iPlayCalledBeforeInitialized = ETrue;
   973 		}
   974 #endif
   975 	
   976 	TInt error = KErrNone;
   977 	switch (iToneConfig->Type())
   978 		{
   979 		case CMMFToneConfig::EMmfToneTypeSimple:
   980 			{
   981 			CMMFSimpleToneConfig* c = STATIC_CAST(CMMFSimpleToneConfig*, iToneConfig);
   982 			TRAP(error, iDevSound->PlayToneL(c->Frequency(), c->Duration()));
   983 			break;
   984 			}
   985 		case CMMFToneConfig::EMmfToneTypeDual:
   986 			{
   987 			CMMFDualToneConfig* c = STATIC_CAST(CMMFDualToneConfig*, iToneConfig);
   988 			TRAP(error, iDevSound->PlayDualToneL(c->FrequencyOne(), c->FrequencyTwo(), c->Duration()));
   989 			break;
   990 			}
   991 		case CMMFToneConfig::EMmfToneTypeDTMF:
   992 			{
   993 			CMMFDTMFStringToneConfig* c = STATIC_CAST(CMMFDTMFStringToneConfig*, iToneConfig);
   994 			TRAP(error, iDevSound->PlayDTMFStringL(c->DTMF()));
   995 			break;
   996 			}
   997 		case CMMFToneConfig::EMmfToneTypeDesSeq:
   998 			{
   999 			CMMFDesSeqToneConfig* c = STATIC_CAST(CMMFDesSeqToneConfig*, iToneConfig);
  1000 			TRAP(error, iDevSound->PlayToneSequenceL(c->DesSeq()));
  1001 			break;
  1002 			}
  1003 		case CMMFToneConfig::EMmfToneTypeFileSeq:
  1004 			{
  1005 			CMMFFileSeqToneConfig* c = STATIC_CAST(CMMFFileSeqToneConfig*, iToneConfig);
  1006 
  1007 			// check we have rights to play
  1008 			TRAP(error, c->ExecuteIntentL());
  1009 
  1010 			// if we have rights then go ahead and play
  1011 			if (error == KErrNone)
  1012 				{
  1013 				TRAP(error, iDevSound->PlayToneSequenceL(c->FileSeq()));
  1014 				}
  1015 
  1016 			break;
  1017 			}
  1018 		case CMMFToneConfig::EMmfToneTypeFixedSeq:
  1019 			{
  1020 			CMMFFixedSeqToneConfig* c = STATIC_CAST(CMMFFixedSeqToneConfig*, iToneConfig);
  1021 			TRAP(error, iDevSound->PlayFixedSequenceL(c->SequenceNumber()));
  1022 			break;
  1023 			}
  1024 		default:
  1025 			{	
  1026 			User::Panic(KMMFMdaAudioToneUtilityPanicCategory, EMMFMdaAudioToneUtilityBadToneConfig);
  1027 			break;
  1028 			}
  1029 		}
  1030 
  1031 	// If there was an error, notify the client now.  Otherwise, client will be notified when
  1032 	// play has finished.
  1033 	if (error)
  1034 		{
  1035 		iState = EMdaAudioToneUtilityNotReady;
  1036 		iAsyncCallback->MatoPlayComplete(error);
  1037 		}
  1038 	else
  1039 		{
  1040         if(iPlayStartObserver)
  1041             {
  1042             iAsyncCallback->MatoPlayStarted(KErrNone);
  1043             }
  1044 		}
  1045 	}
  1046 	
  1047 void CMMFMdaAudioToneUtility::CancelPlay()
  1048 	{
  1049 	iDevSound->Stop();
  1050 
  1051 	if(iState == EMdaAudioToneUtilityPlaying || iState == EMdaAudioToneUtilityPaused)
  1052 		{
  1053 		iState = EMdaAudioToneUtilityPrepared;
  1054 		}
  1055 	// Cancel the AO
  1056 	iAsyncCallback->Cancel();
  1057 	iPlayCalled = EFalse;
  1058 	}
  1059 	
  1060 
  1061 void CMMFMdaAudioToneUtility::SendEventToClient(const TMMFEvent& /*aEvent*/)
  1062 	{
  1063 	if(iState == EMdaAudioToneUtilityPlaying)
  1064 		{
  1065 		iState = EMdaAudioToneUtilityPrepared;
  1066 		}
  1067 
  1068 	iAsyncCallback->MatoPlayComplete(KErrInUse);
  1069 	}
  1070 
  1071 
  1072 void CMMFMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
  1073 	{
  1074 	iPlayStartObserver = &aObserver;
  1075 	}
  1076 
  1077 void CMMFMdaAudioToneUtility::MatoPrepareComplete(TInt aError)
  1078 	{
  1079 	if (!aError)
  1080 		{
  1081 		iState = EMdaAudioToneUtilityPrepared;
  1082 		}
  1083 	else 
  1084 		{
  1085 		iState = EMdaAudioToneUtilityNotReady;
  1086 		}
  1087 
  1088 	iCallback.MatoPrepareComplete(aError);
  1089 	}
  1090 
  1091 void CMMFMdaAudioToneUtility::MatoPlayComplete(TInt aError)
  1092 	{
  1093 	iState = EMdaAudioToneUtilityPrepared;
  1094 	iCallback.MatoPlayComplete(aError);
  1095 	}
  1096 
  1097 void CMMFMdaAudioToneUtility::MatoPlayStarted(TInt aError)
  1098 	{
  1099 	__ASSERT_DEBUG(aError==KErrNone, Panic(EPlayStartedCalledWithError));
  1100 	
  1101 	// Not always there is an observer registered
  1102 	if(iPlayStartObserver)
  1103 		{
  1104 		iPlayStartObserver->MatoPlayStarted(aError);
  1105 		}
  1106 	}
  1107 
  1108 // CustomInferface - just pass on to DevSound. 
  1109 TAny* CMMFMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
  1110 	{
  1111 	return iDevSound->CustomInterface(aInterfaceId);
  1112 	}
  1113 
  1114 
  1115 CMMFMdaAudioToneObserverCallback* CMMFMdaAudioToneObserverCallback::NewL(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback)
  1116 	{
  1117 	return new(ELeave) CMMFMdaAudioToneObserverCallback(aCallback, aPlayStartCallback);
  1118 	}
  1119 
  1120 CMMFMdaAudioToneObserverCallback::CMMFMdaAudioToneObserverCallback(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback) :
  1121 	CActive(CActive::EPriorityHigh),
  1122 	iCallback(aCallback),
  1123 	iPlayStartCallback(aPlayStartCallback)
  1124 	{
  1125 	CActiveScheduler::Add(this);
  1126 	}
  1127 
  1128 CMMFMdaAudioToneObserverCallback::~CMMFMdaAudioToneObserverCallback()
  1129 	{
  1130 	Cancel();
  1131 	}
  1132 
  1133 void CMMFMdaAudioToneObserverCallback::MatoPrepareComplete(TInt aError)
  1134 	{
  1135 	if(!IsActive())
  1136 	    {
  1137         iAction = EPrepareComplete;
  1138         iErrorCode = aError;
  1139         
  1140         TRequestStatus* s = &iStatus;
  1141         SetActive();
  1142         User::RequestComplete(s, KErrNone);
  1143 	    }
  1144 	else
  1145 	    {
  1146 		// Since the default granularity is 8, failing of Append() is unusual, hence ignoring the return err.
  1147 	    iCallBackQueue.Append(EPrepareComplete);
  1148 	    iCallBackQueueError.Append(aError);
  1149 	    }
  1150 	}
  1151 
  1152 void CMMFMdaAudioToneObserverCallback::MatoPlayComplete(TInt aError)
  1153 	{
  1154     if(!IsActive())
  1155         {
  1156         iAction = EPlayComplete;
  1157         iErrorCode = aError;
  1158         
  1159         TRequestStatus* s = &iStatus;
  1160         SetActive();
  1161         User::RequestComplete(s, KErrNone);
  1162         }
  1163     else
  1164         {
  1165         iCallBackQueue.Append(EPlayComplete);
  1166         iCallBackQueueError.Append(aError);
  1167         }
  1168 	}
  1169 
  1170 void CMMFMdaAudioToneObserverCallback::MatoPlayStarted(TInt aError)
  1171 	{
  1172     if(!IsActive())
  1173         {
  1174         iAction = EPlayStarted;
  1175         iErrorCode = aError;
  1176     
  1177         TRequestStatus* s = &iStatus;
  1178         SetActive();
  1179         User::RequestComplete(s, KErrNone);
  1180         }
  1181     else
  1182         {
  1183         iCallBackQueue.Append(EPlayStarted);
  1184         iCallBackQueueError.Append(aError);
  1185         }
  1186 	}
  1187 
  1188 void CMMFMdaAudioToneObserverCallback::RunL()
  1189 	{
  1190 	switch (iAction)
  1191 		{
  1192 		case EPrepareComplete:
  1193 			{
  1194 			iCallback.MatoPrepareComplete(iErrorCode);
  1195 			break;
  1196 			}
  1197 		case EPlayComplete:
  1198 			{
  1199 			iCallback.MatoPlayComplete(iErrorCode);
  1200 			break;
  1201 			}
  1202 		case EPlayStarted:
  1203 			iPlayStartCallback.MatoPlayStarted(iErrorCode);
  1204 			break;
  1205 		}
  1206 	if(iCallBackQueue.Count() > 0 & !IsActive() )
  1207 	    {
  1208         iAction = TMMFAudioToneObserverCallbackAction(iCallBackQueue[0]);
  1209         iCallBackQueue.Remove(0);
  1210         iErrorCode = iCallBackQueueError[0];
  1211         iCallBackQueueError.Remove(0);
  1212         
  1213         TRequestStatus* s = &iStatus;
  1214         User::RequestComplete(s, KErrNone);
  1215         SetActive();
  1216 	    }
  1217 	}
  1218 
  1219 void CMMFMdaAudioToneObserverCallback::DoCancel()
  1220 	{
  1221 	//nothing to cancel
  1222 	}
  1223 
  1224 
  1225 
  1226 
  1227 
  1228 
  1229 // Tone config classes
  1230 
  1231 // Simple Tone
  1232 CMMFToneConfig* CMMFSimpleToneConfig::NewL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
  1233 	{
  1234 	return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFSimpleToneConfig(aFrequency, aDuration));
  1235 	}
  1236 
  1237 CMMFSimpleToneConfig::CMMFSimpleToneConfig(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) :
  1238 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeSimple),
  1239 	iFrequency(aFrequency),
  1240 	iDuration(aDuration)
  1241 	{
  1242 	}
  1243 
  1244 CMMFSimpleToneConfig::~CMMFSimpleToneConfig()
  1245 	{
  1246 	}
  1247 
  1248 TInt CMMFSimpleToneConfig::Frequency()
  1249 	{
  1250 	return iFrequency;
  1251 	}
  1252 
  1253 const TTimeIntervalMicroSeconds& CMMFSimpleToneConfig::Duration()
  1254 	{
  1255 	return iDuration;
  1256 	}
  1257 
  1258 
  1259 // Dual Tone 
  1260 CMMFToneConfig* CMMFDualToneConfig::NewL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
  1261 	{
  1262 	return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFDualToneConfig(aFrequencyOne, aFrequencyTwo, aDuration));
  1263 	}
  1264 
  1265 CMMFDualToneConfig::CMMFDualToneConfig(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) :
  1266 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDual),
  1267 	iFrequencyOne(aFrequencyOne),
  1268 	iFrequencyTwo(aFrequencyTwo),
  1269 	iDuration(aDuration)
  1270 	{
  1271 	}
  1272 
  1273 CMMFDualToneConfig::~CMMFDualToneConfig()
  1274 	{
  1275 	}
  1276 
  1277 TInt CMMFDualToneConfig::FrequencyOne()
  1278 	{
  1279 	return iFrequencyOne;
  1280 	}
  1281 
  1282 TInt CMMFDualToneConfig::FrequencyTwo()
  1283 	{
  1284 	return iFrequencyTwo;
  1285 	}
  1286 
  1287 const TTimeIntervalMicroSeconds& CMMFDualToneConfig::Duration()
  1288 	{
  1289 	return iDuration;
  1290 	}
  1291 
  1292 
  1293 CMMFToneConfig* CMMFDTMFStringToneConfig::NewL(const TDesC& aDTMF)
  1294 	{
  1295 	CMMFDTMFStringToneConfig* s = new(ELeave) CMMFDTMFStringToneConfig;
  1296 	CleanupStack::PushL(s);
  1297 	s->ConstructL(aDTMF);
  1298 	CleanupStack::Pop();
  1299 	return STATIC_CAST(CMMFToneConfig*, s);
  1300 	}
  1301 
  1302 CMMFDTMFStringToneConfig::CMMFDTMFStringToneConfig() :
  1303 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDTMF)
  1304 	{
  1305 	}
  1306 
  1307 LOCAL_C void validateDTMFL(const TDesC& aDTMF)
  1308 //
  1309 // Validate that the supplied DTMf string contains only playable characters
  1310 // 
  1311 	{
  1312 	TInt stringLength = aDTMF.Length();
  1313 	TChar ch;
  1314 	for (TInt index = 0; index < stringLength ; index++)
  1315 		{
  1316 		ch = aDTMF[index];
  1317 		if (!ch.IsDigit() && !ch.IsHexDigit() && !ch.IsSpace() &&
  1318 			(ch != '*') && (ch != '#') && (ch != ','))
  1319 			{
  1320 			User::Leave(KErrArgument); // Bad DTMF string
  1321 			}
  1322 		}
  1323 	}
  1324 
  1325 void CMMFDTMFStringToneConfig::ConstructL(const TDesC& aDTMF)
  1326 	{
  1327 	validateDTMFL(aDTMF);
  1328 	iDTMF = aDTMF.AllocL();
  1329 	}
  1330 
  1331 CMMFDTMFStringToneConfig::~CMMFDTMFStringToneConfig()
  1332 	{
  1333 	delete iDTMF;
  1334 	}
  1335 
  1336 const TDesC& CMMFDTMFStringToneConfig::DTMF()
  1337 	{
  1338 	return *iDTMF;
  1339 	}
  1340 
  1341 
  1342 CMMFToneConfig* CMMFDesSeqToneConfig::NewL(const TDesC8& aDesSeq)
  1343 	{
  1344 	CMMFDesSeqToneConfig* s = new(ELeave) CMMFDesSeqToneConfig;
  1345 	CleanupStack::PushL(s);
  1346 	s->ConstructL(aDesSeq);
  1347 	CleanupStack::Pop();
  1348 	return STATIC_CAST(CMMFToneConfig*, s);
  1349 	}
  1350 
  1351 CMMFDesSeqToneConfig::CMMFDesSeqToneConfig() :
  1352 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDesSeq)
  1353 	{
  1354 	}
  1355 
  1356 void CMMFDesSeqToneConfig::ConstructL(const TDesC8& aDesSeq)
  1357 	{
  1358 	iDesSeq = aDesSeq.AllocL();
  1359 	}
  1360 
  1361 CMMFDesSeqToneConfig::~CMMFDesSeqToneConfig()
  1362 	{
  1363 	delete iDesSeq;
  1364 	}
  1365 
  1366 const TDesC8& CMMFDesSeqToneConfig::DesSeq()
  1367 	{
  1368 	return *iDesSeq;
  1369 	}
  1370 
  1371 
  1372 CMMFToneConfig* CMMFFileSeqToneConfig::NewL(const TDesC& aFileSeq)
  1373 	{
  1374 	CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig;
  1375 	CleanupStack::PushL(s);
  1376 	s->ConstructL(aFileSeq);
  1377 	CleanupStack::Pop();
  1378 	return STATIC_CAST(CMMFToneConfig*, s);
  1379 	}
  1380 
  1381 CMMFFileSeqToneConfig::CMMFFileSeqToneConfig() :
  1382 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFileSeq)
  1383 	{
  1384 	}
  1385 
  1386 void CMMFFileSeqToneConfig::ConstructL(const TDesC& aFileSeq)
  1387 	{
  1388 	// get access to DRM content through filename
  1389 	iCAFContent = CContent::NewL(aFileSeq);
  1390 	
  1391 	// open the CAF source with play intent
  1392 	iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject);
  1393 
  1394 	// read into a descriptor
  1395 	TInt dataSize = 0;
  1396 	iCAFData->DataSizeL(dataSize);
  1397 
  1398 	iDesSeq = HBufC8::NewL(dataSize);
  1399 	TPtr8 desSeqPtr = iDesSeq->Des();
  1400 	iCAFData->Read(desSeqPtr);	
  1401 	}
  1402 	
  1403 	
  1404 
  1405 CMMFToneConfig* CMMFFileSeqToneConfig::NewL(RFile& aFile)
  1406 	{
  1407 	CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig;
  1408 	CleanupStack::PushL(s);
  1409 	s->ConstructL(aFile);
  1410 	CleanupStack::Pop();
  1411 	return STATIC_CAST(CMMFToneConfig*, s);
  1412 	}
  1413 
  1414 
  1415 void CMMFFileSeqToneConfig::ConstructL(RFile& aFile)
  1416 	{
  1417 	// get DRM access to file handle
  1418 	iCAFContent = CContent::NewL(aFile);
  1419 	
  1420 	// open the CAF source with play intent
  1421 	iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject);
  1422 
  1423 	// read into a descriptor
  1424 	TInt dataSize = 0;
  1425 	iCAFData->DataSizeL(dataSize);
  1426 
  1427 	iDesSeq = HBufC8::NewL(dataSize);
  1428 	TPtr8 desSeqPtr = iDesSeq->Des();
  1429 	iCAFData->Read(desSeqPtr);	
  1430 	}
  1431 
  1432 
  1433 CMMFFileSeqToneConfig::~CMMFFileSeqToneConfig()
  1434 	{
  1435 	delete iCAFData;
  1436 	iCAFData = NULL;
  1437 
  1438 	delete iCAFContent;
  1439 	iCAFContent = NULL;
  1440 
  1441 	delete iDesSeq;
  1442 	}
  1443 
  1444 const TDesC8& CMMFFileSeqToneConfig::FileSeq()
  1445 	{
  1446 	return *iDesSeq;
  1447 	}
  1448 
  1449 void CMMFFileSeqToneConfig::ExecuteIntentL()
  1450 	{
  1451 	if (iCAFData)
  1452 		{
  1453 		User::LeaveIfError(iCAFData->ExecuteIntent(ContentAccess::EPlay));
  1454 		}
  1455 	}
  1456 
  1457 CMMFToneConfig* CMMFFixedSeqToneConfig::NewL(TInt aSeqNo)
  1458 	{
  1459 	return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFFixedSeqToneConfig(aSeqNo));
  1460 	}
  1461 
  1462 CMMFFixedSeqToneConfig::CMMFFixedSeqToneConfig(TInt aSeqNo) :
  1463 	CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFixedSeq),
  1464 	iSequenceNumber(aSeqNo)
  1465 	{
  1466 	}
  1467 
  1468 CMMFFixedSeqToneConfig::~CMMFFixedSeqToneConfig()
  1469 	{
  1470 	}
  1471 
  1472 TInt CMMFFixedSeqToneConfig::SequenceNumber()
  1473 	{
  1474 	return iSequenceNumber;
  1475 	}