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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <mmf/common/mmfpaniccodes.h>
18 #include "mmfclienttoneplayer.h"
19 using namespace ContentAccess;
20 enum TMmfMdaAudioToneUtility
23 EPostConditionViolation,
24 EPlayStartedCalledWithError
27 // declared in the recorder module
28 void Panic(TInt aPanicCode);
31 Creates a new instance of the tone player utility.
32 The default volume is set to MaxVolume() / 2.
35 A class to receive notifications from the tone player.
37 This parameter is no longer used and should be NULL.
39 @return A pointer to the new audio tone player utility object.
43 EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* aServer /*= NULL*/)
45 return CMdaAudioToneUtility::NewL(aObserver, aServer, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
49 Creates a new instance of the tone player utility.
50 The default volume is set to MaxVolume() / 2.
53 A class to receive notifications from the tone player
55 This parameter is no longer used and should be NULL
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.
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
65 @return A pointer to the new audio tone player utility object.
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.
75 EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
76 TInt aPriority /*= EMdaPriorityNormal*/,
77 TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
79 CMdaAudioToneUtility* self = new(ELeave) CMdaAudioToneUtility();
80 CleanupStack::PushL(self);
81 self->iProperties = CMMFMdaAudioToneUtility::NewL(aObserver, NULL, aPriority, aPref);
82 CleanupStack::Pop(); //self
87 Destructor. Frees any resources held by the tone player
91 CMdaAudioToneUtility::~CMdaAudioToneUtility()
97 Returns the current state of the audio tone utility.
99 @return The state of the audio tone utility.
103 TMdaAudioToneUtilityState CMdaAudioToneUtility::State()
106 return iProperties->State();
110 Returns the maximum volume supported by the device. This is the maximum value which can be
111 passed to CMdaAudioToneUtility::SetVolume().
113 @return The maximum volume. This value is platform dependent but is always greater than or equal to one.
117 TInt CMdaAudioToneUtility::MaxVolume()
120 return iProperties->MaxVolume();
124 Returns an integer representing the current volume of the audio device.
126 @return The current volume.
130 TInt CMdaAudioToneUtility::Volume()
133 return iProperties->Volume();
137 Changes the volume of the audio device.
139 The volume can be changed before or during play and is effective
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.
151 void CMdaAudioToneUtility::SetVolume(TInt aVolume)
154 iProperties->SetVolume(aVolume);
158 Changes the clients priority.
163 The Priority Preference.
165 @see CMdaAudioToneUtility::NewL()
170 void CMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
173 iProperties->SetPriority(aPriority, aPref);
177 Changes the duration of DTMF tones, the gaps between DTMF tones and the
181 The duration of the DTMF tone in microseconds.
182 @param aToneOffLength
183 The gap between DTFM tones in microseconds.
185 Pauses in microseconds
187 void CMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
188 TTimeIntervalMicroSeconds32 aToneOffLength,
189 TTimeIntervalMicroSeconds32 aPauseLength)
192 iProperties->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength);
196 Sets the number of times the tone sequence is to be repeated during
199 A period of silence can follow each playing of the tone sequence. The
200 tone sequence can be repeated indefinitely.
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.
215 void CMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes,
216 const TTimeIntervalMicroSeconds& aTrailingSilence)
219 iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
223 Defines the period over which the volume level is to rise smoothly
224 from nothing to the normal volume level.
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.
235 void CMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
238 iProperties->SetVolumeRamp(aRampDuration);
242 Returns the number of available pre-defined tone sequences.
244 @return The number of tone sequences. This value is implementation
245 dependent but is always greater than or equal to zero.
249 TInt CMdaAudioToneUtility::FixedSequenceCount()
252 return iProperties->FixedSequenceCount();
256 Returns the name assigned to a specific pre-defined tone sequence.
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
265 @see CMMFDevSound::FixedSequenceName(TInt aSequenceNumber)
266 @see FixedSequenceCount()
268 @return The name assigned to the tone sequence.
272 const TDesC& CMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
275 return iProperties->FixedSequenceName(aSequenceNumber);
279 Configures the audio tone player utility to play a single tone.
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.
289 The frequency (pitch) of the tone in Hz.
291 The duration of the tone in microseconds.
294 void CMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
297 iProperties->PrepareToPlayTone(aFrequency, aDuration);
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.
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.
313 The first frequency (pitch) of the tone.
315 The second frequency (pitch) of the tone.
317 The duration of the tone in microseconds.
321 EXPORT_C void CMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
324 iProperties->PrepareToPlayDualTone(aFrequencyOne, aFrequencyTwo, aDuration);
328 Configures the audio tone utility player to play a DTMF (Dual-Tone
329 Multi-Frequency) string.
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.
339 A descriptor containing the DTMF string.
343 void CMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
346 iProperties->PrepareToPlayDTMFString(aDTMF);
350 Configures the audio tone player utility to play a tone sequence
351 contained in a descriptor.
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.
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.
368 void CMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
371 iProperties->PrepareToPlayDesSequence(aSequence);
375 Configures the audio tone player utility to play a tone sequence
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.
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.
393 void CMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
396 iProperties->PrepareToPlayFileSequence(aFileName);
400 Configures the audio tone player utility to play a tone sequence
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.
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.
418 EXPORT_C void CMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFile)
421 iProperties->PrepareToPlayFileSequence(aFile);
426 Configures the audio tone player utility to play the specified
427 pre-defined tone sequence.
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.
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.
443 @see FixedSequenceCount()
444 @see CMMFDevSound::PlayFixedSequenceL(TInt aSequenceNumber)
448 void CMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
451 iProperties->PrepareToPlayFixedSequence(aSequenceNumber);
455 Cancels the configuration operation.
457 The observer callback function
458 MMdaAudioToneObserver::MatoPrepareComplete() is not
463 void CMdaAudioToneUtility::CancelPrepare()
466 iProperties->CancelPrepare();
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().
481 void CMdaAudioToneUtility::Play()
487 EXPORT_C TInt CMdaAudioToneUtility::Pause()
490 return iProperties->Pause();
493 EXPORT_C TInt CMdaAudioToneUtility::Resume()
496 return iProperties->Resume();
500 Cancels the tone playing operation.
502 The observer callback
503 function MMdaAudioToneObserver::MatoPlayComplete() is not
508 void CMdaAudioToneUtility::CancelPlay()
511 iProperties->CancelPlay();
515 Sets the stereo balance for playback.
518 The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
520 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
521 another of the system-wide error codes.
525 EXPORT_C void CMdaAudioToneUtility::SetBalanceL(TInt aBalance /*=KMMFBalanceCenter*/)
528 iProperties->SetBalanceL(aBalance);
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.
536 * @return The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
540 EXPORT_C TInt CMdaAudioToneUtility::GetBalanceL()
543 return iProperties->GetBalanceL();
547 Retrieves a custom interface to the underlying device.
550 The interface UID, defined with the custom interface.
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.
556 EXPORT_C TAny* CMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
559 return iProperties->CustomInterface(aInterfaceId);
562 EXPORT_C void CMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
565 iProperties->RegisterPlayStartCallback(aObserver);
570 CMMFMdaAudioToneUtility* CMMFMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
571 TInt aPriority /*= EMdaPriorityNormal*/,
572 TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
575 CMMFMdaAudioToneUtility* self = new(ELeave) CMMFMdaAudioToneUtility(aObserver, aPriority, aPref);
576 CleanupStack::PushL(self);
578 CleanupStack::Pop(self);
584 CMMFMdaAudioToneUtility::CMMFMdaAudioToneUtility(MMdaAudioToneObserver& aCallback, TInt aPriority, TInt aPref) :
587 iPrioritySettings.iPref = aPref;
588 iPrioritySettings.iPriority = aPriority;
589 iState = EMdaAudioToneUtilityNotReady;
590 iInitialized = EFalse;
591 iPlayCalled = EFalse;
594 iPlayCalledBeforeInitialized = EFalse;
598 void CMMFMdaAudioToneUtility::ConstructL()
600 iAsyncCallback = CMMFMdaAudioToneObserverCallback::NewL(*this, *this);
602 iDevSound = CMMFDevSound::NewL();
603 iDevSound->InitializeL(*this,EMMFStateTonePlaying);
605 // In some implementations InitializeComplete() returns in the InitializeL() context,
607 User::LeaveIfError(iInitializeState);
609 iDevSound->SetPrioritySettings(iPrioritySettings);
610 SetVolume(MaxVolume()/2 ); // set the volume to an intermediate value
613 CMMFMdaAudioToneUtility::~CMMFMdaAudioToneUtility()
616 delete iAsyncCallback;
622 void CMMFMdaAudioToneUtility::InitializeComplete(TInt aError)
625 __ASSERT_ALWAYS(!iPlayCalledBeforeInitialized, User::Panic(_L("PlayInitialized called before InitializeComplete"), 0));
627 iInitialized = ETrue;
631 // Play() is called before InitializeComplete()
632 if (aError == KErrNone)
634 PlayAfterInitialized();
638 // InitializeComplete() with error other than KErrNone
639 iState = EMdaAudioToneUtilityNotReady;
640 iAsyncCallback->MatoPlayComplete(aError);
642 iPlayCalled = EFalse;
644 iInitializeState = aError;
647 void CMMFMdaAudioToneUtility::ToneFinished(TInt aError)
649 if (aError != KErrCancel)
651 if (aError == KErrUnderflow)
656 iAsyncCallback->MatoPlayComplete(aError);
658 // else don't want to callback after a cancel
662 TMdaAudioToneUtilityState CMMFMdaAudioToneUtility::State()
667 TInt CMMFMdaAudioToneUtility::MaxVolume()
669 return iDevSound->MaxVolume();
672 TInt CMMFMdaAudioToneUtility::Volume()
674 return iDevSound->Volume();
677 void CMMFMdaAudioToneUtility::SetVolume(TInt aVolume)
679 iDevSound->SetVolume(aVolume);
682 void CMMFMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
684 iPrioritySettings.iPref = aPref;
685 iPrioritySettings.iPriority = aPriority;
686 iDevSound->SetPrioritySettings(iPrioritySettings);
689 void CMMFMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
690 TTimeIntervalMicroSeconds32 aToneOffLength,
691 TTimeIntervalMicroSeconds32 aPauseLength)
693 iDevSound->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength);
696 void CMMFMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
698 iDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence);
701 void CMMFMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
703 iDevSound->SetVolumeRamp(aRampDuration);
706 TInt CMMFMdaAudioToneUtility::FixedSequenceCount()
708 return iDevSound->FixedSequenceCount();
711 const TDesC& CMMFMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
713 return iDevSound->FixedSequenceName(aSequenceNumber);
722 * follows a simple straight line transformation
724 * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100
725 * c = KMMFBalanceMaxRight
728 * KMMFBalanceMaxRight = m * 0 + c
729 * c = KMMFBalanceMaxRight
731 * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight
732 * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100
734 void CMMFMdaAudioToneUtility::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
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) );
741 aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
743 //[ assert post condition that aBalance is within limits ]
744 __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
750 * CalculateLeftRightBalance
755 * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight)
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 )
768 void CMMFMdaAudioToneUtility::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
770 // [ assert precondition that aBalance is within limits ]
771 __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
773 //[ Now separate percentage balances out from aBalance ]
774 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
775 aRight = 100 - aLeft;
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));
783 void CMMFMdaAudioToneUtility::SetBalanceL(TInt aBalance)
787 CalculateLeftRightBalance(left,right,aBalance);
788 iDevSound->SetPlayBalanceL(left,right);
791 TInt CMMFMdaAudioToneUtility::GetBalanceL()
796 iDevSound->GetPlayBalanceL(left, right);
797 CalculateBalance(balance,left,right);
801 void CMMFMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
805 TRAPD(error, iToneConfig = CMMFSimpleToneConfig::NewL(aFrequency, aDuration));
806 iAsyncCallback->MatoPrepareComplete(error);
809 void CMMFMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
813 TRAPD(error, iToneConfig = CMMFDualToneConfig::NewL(aFrequencyOne, aFrequencyTwo, aDuration));
814 iAsyncCallback->MatoPrepareComplete(error);
817 void CMMFMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
821 TRAPD(error, iToneConfig = CMMFDTMFStringToneConfig::NewL(aDTMF));
822 iAsyncCallback->MatoPrepareComplete(error);
825 void CMMFMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
829 TRAPD(error, iToneConfig = CMMFDesSeqToneConfig::NewL(aSequence));
830 iAsyncCallback->MatoPrepareComplete(error);
833 void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
837 TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName));
838 iAsyncCallback->MatoPrepareComplete(error);
841 void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFileName)
845 TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName));
846 iAsyncCallback->MatoPrepareComplete(error);
852 void CMMFMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
856 TRAPD(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(aSequenceNumber));
857 iSequenceNumber = aSequenceNumber;
858 iAsyncCallback->MatoPrepareComplete(error);
861 void CMMFMdaAudioToneUtility::CancelPrepare()
863 // xxx - do we need to cancel the callback? What if the callback is actually calling back another error? Probably best not to cancel...
867 if (iState == EMdaAudioToneUtilityPrepared)
869 iState = EMdaAudioToneUtilityNotReady;
872 iAsyncCallback->Cancel();
875 TInt CMMFMdaAudioToneUtility::Pause()
877 // Handle scenario when Pause is called before playback has started
878 if (iState != EMdaAudioToneUtilityPlaying || (iState == EMdaAudioToneUtilityPlaying && !iInitialized))
883 else if(! iDevSound->IsResumeSupported() || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq)
885 return KErrNotSupported;
889 iState = EMdaAudioToneUtilityPaused;
893 TInt CMMFMdaAudioToneUtility::Resume()
896 if (iState != EMdaAudioToneUtilityPaused)
901 else if( iDevSound->IsResumeSupported() == EFalse || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq)
903 err = KErrNotSupported;
908 err = iDevSound->Resume();
911 iState = EMdaAudioToneUtilityPlaying;
917 void CMMFMdaAudioToneUtility::Play()
919 TInt error = KErrNone;
921 if ((iState == EMdaAudioToneUtilityPlaying) || (iState == EMdaAudioToneUtilityPaused) || iPlayCalled)
930 TRAP(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(iSequenceNumber));
933 // If there was an error, notify the client now. Otherwise, client will be notified when
934 // play has finished.
937 iState = EMdaAudioToneUtilityNotReady;
938 iAsyncCallback->MatoPlayComplete(error);
943 iState = EMdaAudioToneUtilityPlaying;
947 // Play() is called after InitializeComplete()
948 if (iInitializeState)
950 // InitializeComplete() with error other than KErrNone
951 iState = EMdaAudioToneUtilityNotReady;
952 iAsyncCallback->MatoPlayComplete(iInitializeState);
956 PlayAfterInitialized();
961 // Play() is called before InitializeComplete()
967 void CMMFMdaAudioToneUtility::PlayAfterInitialized()
970 if (iInitialized == EFalse)
972 iPlayCalledBeforeInitialized = ETrue;
976 TInt error = KErrNone;
977 switch (iToneConfig->Type())
979 case CMMFToneConfig::EMmfToneTypeSimple:
981 CMMFSimpleToneConfig* c = STATIC_CAST(CMMFSimpleToneConfig*, iToneConfig);
982 TRAP(error, iDevSound->PlayToneL(c->Frequency(), c->Duration()));
985 case CMMFToneConfig::EMmfToneTypeDual:
987 CMMFDualToneConfig* c = STATIC_CAST(CMMFDualToneConfig*, iToneConfig);
988 TRAP(error, iDevSound->PlayDualToneL(c->FrequencyOne(), c->FrequencyTwo(), c->Duration()));
991 case CMMFToneConfig::EMmfToneTypeDTMF:
993 CMMFDTMFStringToneConfig* c = STATIC_CAST(CMMFDTMFStringToneConfig*, iToneConfig);
994 TRAP(error, iDevSound->PlayDTMFStringL(c->DTMF()));
997 case CMMFToneConfig::EMmfToneTypeDesSeq:
999 CMMFDesSeqToneConfig* c = STATIC_CAST(CMMFDesSeqToneConfig*, iToneConfig);
1000 TRAP(error, iDevSound->PlayToneSequenceL(c->DesSeq()));
1003 case CMMFToneConfig::EMmfToneTypeFileSeq:
1005 CMMFFileSeqToneConfig* c = STATIC_CAST(CMMFFileSeqToneConfig*, iToneConfig);
1007 // check we have rights to play
1008 TRAP(error, c->ExecuteIntentL());
1010 // if we have rights then go ahead and play
1011 if (error == KErrNone)
1013 TRAP(error, iDevSound->PlayToneSequenceL(c->FileSeq()));
1018 case CMMFToneConfig::EMmfToneTypeFixedSeq:
1020 CMMFFixedSeqToneConfig* c = STATIC_CAST(CMMFFixedSeqToneConfig*, iToneConfig);
1021 TRAP(error, iDevSound->PlayFixedSequenceL(c->SequenceNumber()));
1026 User::Panic(KMMFMdaAudioToneUtilityPanicCategory, EMMFMdaAudioToneUtilityBadToneConfig);
1031 // If there was an error, notify the client now. Otherwise, client will be notified when
1032 // play has finished.
1035 iState = EMdaAudioToneUtilityNotReady;
1036 iAsyncCallback->MatoPlayComplete(error);
1040 if(iPlayStartObserver)
1042 iAsyncCallback->MatoPlayStarted(KErrNone);
1047 void CMMFMdaAudioToneUtility::CancelPlay()
1051 if(iState == EMdaAudioToneUtilityPlaying || iState == EMdaAudioToneUtilityPaused)
1053 iState = EMdaAudioToneUtilityPrepared;
1056 iAsyncCallback->Cancel();
1057 iPlayCalled = EFalse;
1061 void CMMFMdaAudioToneUtility::SendEventToClient(const TMMFEvent& /*aEvent*/)
1063 if(iState == EMdaAudioToneUtilityPlaying)
1065 iState = EMdaAudioToneUtilityPrepared;
1068 iAsyncCallback->MatoPlayComplete(KErrInUse);
1072 void CMMFMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
1074 iPlayStartObserver = &aObserver;
1077 void CMMFMdaAudioToneUtility::MatoPrepareComplete(TInt aError)
1081 iState = EMdaAudioToneUtilityPrepared;
1085 iState = EMdaAudioToneUtilityNotReady;
1088 iCallback.MatoPrepareComplete(aError);
1091 void CMMFMdaAudioToneUtility::MatoPlayComplete(TInt aError)
1093 iState = EMdaAudioToneUtilityPrepared;
1094 iCallback.MatoPlayComplete(aError);
1097 void CMMFMdaAudioToneUtility::MatoPlayStarted(TInt aError)
1099 __ASSERT_DEBUG(aError==KErrNone, Panic(EPlayStartedCalledWithError));
1101 // Not always there is an observer registered
1102 if(iPlayStartObserver)
1104 iPlayStartObserver->MatoPlayStarted(aError);
1108 // CustomInferface - just pass on to DevSound.
1109 TAny* CMMFMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
1111 return iDevSound->CustomInterface(aInterfaceId);
1115 CMMFMdaAudioToneObserverCallback* CMMFMdaAudioToneObserverCallback::NewL(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback)
1117 return new(ELeave) CMMFMdaAudioToneObserverCallback(aCallback, aPlayStartCallback);
1120 CMMFMdaAudioToneObserverCallback::CMMFMdaAudioToneObserverCallback(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback) :
1121 CActive(CActive::EPriorityHigh),
1122 iCallback(aCallback),
1123 iPlayStartCallback(aPlayStartCallback)
1125 CActiveScheduler::Add(this);
1128 CMMFMdaAudioToneObserverCallback::~CMMFMdaAudioToneObserverCallback()
1133 void CMMFMdaAudioToneObserverCallback::MatoPrepareComplete(TInt aError)
1137 iAction = EPrepareComplete;
1138 iErrorCode = aError;
1140 TRequestStatus* s = &iStatus;
1142 User::RequestComplete(s, KErrNone);
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);
1152 void CMMFMdaAudioToneObserverCallback::MatoPlayComplete(TInt aError)
1156 iAction = EPlayComplete;
1157 iErrorCode = aError;
1159 TRequestStatus* s = &iStatus;
1161 User::RequestComplete(s, KErrNone);
1165 iCallBackQueue.Append(EPlayComplete);
1166 iCallBackQueueError.Append(aError);
1170 void CMMFMdaAudioToneObserverCallback::MatoPlayStarted(TInt aError)
1174 iAction = EPlayStarted;
1175 iErrorCode = aError;
1177 TRequestStatus* s = &iStatus;
1179 User::RequestComplete(s, KErrNone);
1183 iCallBackQueue.Append(EPlayStarted);
1184 iCallBackQueueError.Append(aError);
1188 void CMMFMdaAudioToneObserverCallback::RunL()
1192 case EPrepareComplete:
1194 iCallback.MatoPrepareComplete(iErrorCode);
1199 iCallback.MatoPlayComplete(iErrorCode);
1203 iPlayStartCallback.MatoPlayStarted(iErrorCode);
1206 if(iCallBackQueue.Count() > 0 & !IsActive() )
1208 iAction = TMMFAudioToneObserverCallbackAction(iCallBackQueue[0]);
1209 iCallBackQueue.Remove(0);
1210 iErrorCode = iCallBackQueueError[0];
1211 iCallBackQueueError.Remove(0);
1213 TRequestStatus* s = &iStatus;
1214 User::RequestComplete(s, KErrNone);
1219 void CMMFMdaAudioToneObserverCallback::DoCancel()
1229 // Tone config classes
1232 CMMFToneConfig* CMMFSimpleToneConfig::NewL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
1234 return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFSimpleToneConfig(aFrequency, aDuration));
1237 CMMFSimpleToneConfig::CMMFSimpleToneConfig(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) :
1238 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeSimple),
1239 iFrequency(aFrequency),
1240 iDuration(aDuration)
1244 CMMFSimpleToneConfig::~CMMFSimpleToneConfig()
1248 TInt CMMFSimpleToneConfig::Frequency()
1253 const TTimeIntervalMicroSeconds& CMMFSimpleToneConfig::Duration()
1260 CMMFToneConfig* CMMFDualToneConfig::NewL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
1262 return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFDualToneConfig(aFrequencyOne, aFrequencyTwo, aDuration));
1265 CMMFDualToneConfig::CMMFDualToneConfig(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) :
1266 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDual),
1267 iFrequencyOne(aFrequencyOne),
1268 iFrequencyTwo(aFrequencyTwo),
1269 iDuration(aDuration)
1273 CMMFDualToneConfig::~CMMFDualToneConfig()
1277 TInt CMMFDualToneConfig::FrequencyOne()
1279 return iFrequencyOne;
1282 TInt CMMFDualToneConfig::FrequencyTwo()
1284 return iFrequencyTwo;
1287 const TTimeIntervalMicroSeconds& CMMFDualToneConfig::Duration()
1293 CMMFToneConfig* CMMFDTMFStringToneConfig::NewL(const TDesC& aDTMF)
1295 CMMFDTMFStringToneConfig* s = new(ELeave) CMMFDTMFStringToneConfig;
1296 CleanupStack::PushL(s);
1297 s->ConstructL(aDTMF);
1298 CleanupStack::Pop();
1299 return STATIC_CAST(CMMFToneConfig*, s);
1302 CMMFDTMFStringToneConfig::CMMFDTMFStringToneConfig() :
1303 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDTMF)
1307 LOCAL_C void validateDTMFL(const TDesC& aDTMF)
1309 // Validate that the supplied DTMf string contains only playable characters
1312 TInt stringLength = aDTMF.Length();
1314 for (TInt index = 0; index < stringLength ; index++)
1317 if (!ch.IsDigit() && !ch.IsHexDigit() && !ch.IsSpace() &&
1318 (ch != '*') && (ch != '#') && (ch != ','))
1320 User::Leave(KErrArgument); // Bad DTMF string
1325 void CMMFDTMFStringToneConfig::ConstructL(const TDesC& aDTMF)
1327 validateDTMFL(aDTMF);
1328 iDTMF = aDTMF.AllocL();
1331 CMMFDTMFStringToneConfig::~CMMFDTMFStringToneConfig()
1336 const TDesC& CMMFDTMFStringToneConfig::DTMF()
1342 CMMFToneConfig* CMMFDesSeqToneConfig::NewL(const TDesC8& aDesSeq)
1344 CMMFDesSeqToneConfig* s = new(ELeave) CMMFDesSeqToneConfig;
1345 CleanupStack::PushL(s);
1346 s->ConstructL(aDesSeq);
1347 CleanupStack::Pop();
1348 return STATIC_CAST(CMMFToneConfig*, s);
1351 CMMFDesSeqToneConfig::CMMFDesSeqToneConfig() :
1352 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDesSeq)
1356 void CMMFDesSeqToneConfig::ConstructL(const TDesC8& aDesSeq)
1358 iDesSeq = aDesSeq.AllocL();
1361 CMMFDesSeqToneConfig::~CMMFDesSeqToneConfig()
1366 const TDesC8& CMMFDesSeqToneConfig::DesSeq()
1372 CMMFToneConfig* CMMFFileSeqToneConfig::NewL(const TDesC& aFileSeq)
1374 CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig;
1375 CleanupStack::PushL(s);
1376 s->ConstructL(aFileSeq);
1377 CleanupStack::Pop();
1378 return STATIC_CAST(CMMFToneConfig*, s);
1381 CMMFFileSeqToneConfig::CMMFFileSeqToneConfig() :
1382 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFileSeq)
1386 void CMMFFileSeqToneConfig::ConstructL(const TDesC& aFileSeq)
1388 // get access to DRM content through filename
1389 iCAFContent = CContent::NewL(aFileSeq);
1391 // open the CAF source with play intent
1392 iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject);
1394 // read into a descriptor
1396 iCAFData->DataSizeL(dataSize);
1398 iDesSeq = HBufC8::NewL(dataSize);
1399 TPtr8 desSeqPtr = iDesSeq->Des();
1400 iCAFData->Read(desSeqPtr);
1405 CMMFToneConfig* CMMFFileSeqToneConfig::NewL(RFile& aFile)
1407 CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig;
1408 CleanupStack::PushL(s);
1409 s->ConstructL(aFile);
1410 CleanupStack::Pop();
1411 return STATIC_CAST(CMMFToneConfig*, s);
1415 void CMMFFileSeqToneConfig::ConstructL(RFile& aFile)
1417 // get DRM access to file handle
1418 iCAFContent = CContent::NewL(aFile);
1420 // open the CAF source with play intent
1421 iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject);
1423 // read into a descriptor
1425 iCAFData->DataSizeL(dataSize);
1427 iDesSeq = HBufC8::NewL(dataSize);
1428 TPtr8 desSeqPtr = iDesSeq->Des();
1429 iCAFData->Read(desSeqPtr);
1433 CMMFFileSeqToneConfig::~CMMFFileSeqToneConfig()
1444 const TDesC8& CMMFFileSeqToneConfig::FileSeq()
1449 void CMMFFileSeqToneConfig::ExecuteIntentL()
1453 User::LeaveIfError(iCAFData->ExecuteIntent(ContentAccess::EPlay));
1457 CMMFToneConfig* CMMFFixedSeqToneConfig::NewL(TInt aSeqNo)
1459 return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFFixedSeqToneConfig(aSeqNo));
1462 CMMFFixedSeqToneConfig::CMMFFixedSeqToneConfig(TInt aSeqNo) :
1463 CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFixedSeq),
1464 iSequenceNumber(aSeqNo)
1468 CMMFFixedSeqToneConfig::~CMMFFixedSeqToneConfig()
1472 TInt CMMFFixedSeqToneConfig::SequenceNumber()
1474 return iSequenceNumber;