Update contrib.
1 // Copyright (c) 2003-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.
17 #include <mmf/server/mmfformat.h>
18 #include <mmf/server/mmfclip.h>
19 #include <mdaaudiosampleeditor.h>
20 #include <mmfcontrollerimplementationuids.hrh>
21 #include <mmf/common/mmffourcc.h>
22 #include <mmf/common/mmfpaniccodes.h>
23 #include "MmfAudioToneController.h"
24 #include <mmf/server/mmfaudiooutput.h>
27 A list of panic codes for the Audio Tone Controller
30 TMmfAudioToneControllerPanics is an enumeration with the following entries:
31 EBadArgument indicates a bad argument
32 EBadState indicates a state viaolation
33 EBadInvariant indicates an invariant violation
34 EBadReset indicates failed reset
35 EPostConditionViolation indicates a post condition violation
37 enum TMmfAudioToneControllerPanics
43 EPostConditionViolation,
47 EMessageAlreadyBeingProcessed,
51 EBadStateToGetDataSource,
52 EBadStateToGetDataSink,
62 ENotReadyForDataSourceRemoval,
63 EBadDataSourceRemoval,
64 ENotReadyForDataSinkRemoval,
66 ENotReadyForCustomCommand,
67 EBadStateAfterNegotiate,
68 EBadStateToSetPriority,
72 EBadStateAfterVolumeSet,
73 EBadStateToGetMaxVolume,
74 EBadStateAfterGetMaxVolume,
76 EBadStateAfterGetVolume,
77 EBadStateToSetVolumeRamp,
78 EBadStateAfterSetVolumeRamp,
79 EBadStateToSetBalance,
80 EBadStateAfterSetBalance,
81 EBadStateToGetBalance,
82 EBadStateAfterGetBalance,
83 EBadStateForTransition,
84 EBadStateAfterTransition,
90 Instantiates a new Audio Tone Controller. Usually invoked from ECom
93 @return CMMFController* bas class for all plugin controllers
95 CMMFController* CMMFAudioToneController::NewL()
97 CMMFAudioToneController* self = new(ELeave) CMMFAudioToneController;
98 CleanupStack::PushL(self);
100 CleanupStack::Pop( self );
101 return STATIC_CAST( CMMFController*, self );
107 2nd Phase constructor
111 void CMMFAudioToneController::ConstructL()
113 iSourceAndSinkAdded = EFalse;
115 // Construct custom command parsers
116 CMMFAudioPlayDeviceCustomCommandParser* audPlayDevParser = CMMFAudioPlayDeviceCustomCommandParser::NewL(*this);
117 CleanupStack::PushL(audPlayDevParser);
118 AddCustomCommandParserL(*audPlayDevParser);
119 CleanupStack::Pop( audPlayDevParser );//audPlayDevParser
121 CMMFAudioPlayControllerCustomCommandParser* audPlayConParser = CMMFAudioPlayControllerCustomCommandParser::NewL(*this);
122 CleanupStack::PushL(audPlayConParser);
123 AddCustomCommandParserL(*audPlayConParser);
124 CleanupStack::Pop(audPlayConParser);//audPlayConParser
126 CMMFAudioPlayControllerSetRepeatsCustomCommandParser* audPlayConSetRepeatsParser = CMMFAudioPlayControllerSetRepeatsCustomCommandParser::NewL(*this);
127 CleanupStack::PushL(audPlayConSetRepeatsParser);
128 AddCustomCommandParserL(*audPlayConSetRepeatsParser);
129 CleanupStack::Pop(audPlayConSetRepeatsParser);
131 // [ assert the invariant now that we are constructed ]
132 __ASSERT_ALWAYS( Invariant(), Panic( EStateNotConstructed));
137 1st Phase constructor
142 CMMFAudioToneController::CMMFAudioToneController() : iState(EStopped)
151 CMMFAudioToneController::~CMMFAudioToneController()
154 delete iToneSequenceData;
159 Adds a data source to the controller
163 @param aSource will provide the data the controller plays
165 void CMMFAudioToneController::AddDataSourceL(MDataSource& aSource)
167 //[ assert the invariant ]
168 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateToGetDataSource));
170 // [ precondition that the controller is stopped ]
171 if( State() != EStopped )
172 User::Leave( KErrNotReady );
174 //[ precondition iData source is not already configured ]
176 User::Leave(KErrAlreadyExists);
178 //Only works with files or descriptors
179 if ((aSource.DataSourceType() != KUidMmfFileSource ) && (aSource.DataSourceType() != KUidMmfDescriptorSource))
180 User::Leave( KErrNotSupported ) ;
183 //extract the tone data into a buffer ready to play.
184 iToneSequenceData = CMMFDataBuffer::NewL(STATIC_CAST(CMMFClip*, &aSource)->Size());
186 aSource.SourcePrimeL();
187 STATIC_CAST(CMMFClip*, &aSource)->ReadBufferL(iToneSequenceData,0);
188 aSource.SourceStopL();
191 //[ its now safe to set the source ]
192 iDataSource = &aSource ;
194 //[ assert the post condition ]
195 __ASSERT_ALWAYS(iDataSource, Panic(EMMFAudioControllerPanicDataSourceDoesNotExist));
197 iDataSource->SetSourcePrioritySettings(iPrioritySettings);
203 Adds a data sink to the controller
207 @param aSink will accept the data the controller plays
209 void CMMFAudioToneController::AddDataSinkL(MDataSink& aSink)
211 //[ assert the invariant ]
212 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateToGetDataSink));
214 // [ precondition that the controller is stopped ]
215 if( State() != EStopped )
216 User::Leave( KErrNotReady );
218 // [ assert precondition that sink does not exist ]
220 User::Leave(KErrAlreadyExists);
222 //Only support playing to audio output
223 if (aSink.DataSinkType() != KUidMmfAudioOutput)
224 User::Leave( KErrNotSupported );
226 iMMFDevSound = CMMFDevSound::NewL();
228 // [ assert post conditions that a sink has been added ]
229 __ASSERT_ALWAYS(iMMFDevSound, Panic(EMMFAudioControllerPanicDataSinkDoesNotExist));
233 Primes the controller, ready for playing
237 @param aMessage allows response to client upon completion or error
239 void CMMFAudioToneController::PrimeL(TMMFMessage& aMessage)
241 //[ assert the invariant ]
242 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateForPrime));
244 //[ assert the precondition ( in a friendly way for this api
245 // that we are either stopped or primed already ]
246 if(!(( State() == EStopped ) || (State() == EPrimed )))
247 User::Leave( KErrNotReady );
249 // [ precondition we have a data source & sink and aren't already processing a message]
250 __ASSERT_ALWAYS( iDataSource, Panic( ENoDataSource));
251 __ASSERT_ALWAYS( iMMFDevSound, Panic( ENoDataSink));
252 __ASSERT_ALWAYS( !iMessage, Panic( EMessageAlreadyBeingProcessed ));
254 if (iState == EStopped)
257 iMessage = new(ELeave) TMMFMessage(aMessage); //store message
258 __ASSERT_ALWAYS( iMessage, Panic( EPostConditionViolation )); //check if message created sucessfully
261 TRAPD(err,NegotiateL());
264 SetState( EStopped );
271 __ASSERT_ALWAYS( Invariant(), Panic( EStateNotPrimed ) );
276 Primes the controller, ready for playingAdds a data sink to the controller
280 void CMMFAudioToneController::PrimeL()
286 This method resets the controller
290 void CMMFAudioToneController::ResetL()
292 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateToReset ) );
294 // Stop recording if it's not stopped,
295 if (State() != EStopped)
300 //[ ensure loggoff of source and sink ]
302 delete iMMFDevSound; iMMFDevSound = NULL ;
303 iSourceAndSinkAdded = EFalse;
308 // [ assert the invariant]
309 __ASSERT_ALWAYS( Invariant(), Panic( EBadResetState ) );
311 __ASSERT_ALWAYS( ResetPostCondition(), Panic( EBadReset ));
312 __ASSERT_ALWAYS( Invariant(), Panic(EBadState));
316 This function determnines if the reset post condition is valid
320 TBool CMMFAudioToneController::ResetPostCondition() const
322 TBool result = EFalse ;
323 if((iMMFDevSound == NULL) &&
324 (iDataSource == NULL) &&
325 (State() == EStopped))
334 Start playing the audio tone, passing the data to Dev Sound
336 The controller will be put into the EPlaying state
340 void CMMFAudioToneController::PlayL()
342 // [ assert the precondition that the
343 // play command is only activated in the primed state]
344 if ( State() != EPrimed && State() != EPausePlaying)
345 User::Leave(KErrNotReady);
347 // [ assert the Invariant ]
348 __ASSERT_ALWAYS( Invariant(), Panic(EStateNotReadyToPlay));
350 if(State() == EPausePlaying && iIsResumeSupported)
352 User::LeaveIfError(iMMFDevSound->Resume());
356 iMMFDevSound->PlayToneSequenceL(iToneSequenceData->Data());
359 SetState( EPlaying );
361 //[ assert the post condition we are playing ]
362 __ASSERT_ALWAYS( (State() == EPlaying ), Panic( EBadState));
363 //[ assert the invariant ]
364 __ASSERT_ALWAYS( Invariant(), Panic(EBadPlayState));
368 This should Pause playing of the audio tone. HOWEVER, this is not possible with a
369 tone sequence. This method is therefore provided as a NOP purely to allow audio
370 clients to operate correctly.
372 The controller will be put into the EPrimed state
376 void CMMFAudioToneController::PauseL()
378 //[ assert the invariant ]
379 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToPause));
381 __ASSERT_ALWAYS(iMMFDevSound, Panic(EMMFAudioControllerPanicDataSinkDoesNotExist));
383 if(iIsResumeSupported)
385 iMMFDevSound->Pause();
386 SetState(EPausePlaying);
390 // If Resume is not supported
391 // this method can't do anything, as we have no interface to restart DevSound
392 // after pausing a tone. It need to be here however as client utility does
393 // Pause() Stop() when stopping.
397 //[ assert the post condition we are stopped ]
398 __ASSERT_ALWAYS( (State() == EPrimed || State() == EPausePlaying), Panic( EBadState));
399 //[ assert the invariant ]
400 __ASSERT_ALWAYS( Invariant(), Panic(EBadPauseState));
404 This stops the tone that is currently playing
405 The controller will be put into the EStopped state
409 void CMMFAudioToneController::StopL()
411 //[ assert the invariant ]
412 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToStop));
414 // [ precondition that we are not already stopped
415 // && if we are stopped do nothing.
416 // Due to the asynchronous nature of the controller
417 // interaction the response to stopped when stopped
418 // should not be an error ]
419 if (State() != EStopped)
421 //[ update state to stopped propogate to devsound ]
422 iMMFDevSound->Stop();
426 //[ assert the post condition we are stopped ]
427 __ASSERT_ALWAYS( (State() == EStopped), Panic( EBadState));
428 //[ assert the invariant ]
429 __ASSERT_ALWAYS( Invariant(), Panic(EBadStopState));
434 Removes a data source form the controller
438 @param aDataSource The source that is to be removed.
440 void CMMFAudioToneController::RemoveDataSourceL(MDataSource& aDataSource )
442 //[ assert the invariant ]
443 __ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForDataSourceRemoval) );
445 //[ precondition is that we have a data source ]
447 User::Leave(KErrNotReady);
449 //[precondition the data source is the data source we have]
450 if( iDataSource != &aDataSource )
451 User::Leave(KErrArgument);
453 //[ the controller is in the stopped state ]
454 if(State() != EStopped)
455 User::Leave(KErrNotReady);
457 //[ remove the data sink from the controller and delete the format]
458 if( iSourceAndSinkAdded )
460 iMMFDevSound->Stop();
461 iSourceAndSinkAdded = EFalse ;
466 // [ assert postcondition we are stopped ]
467 __ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
469 //[ assert postcondition the SourceAndSinkAdded is false ]
470 __ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
472 //[ assert postcondition the data sink is null ]
473 __ASSERT_ALWAYS( (iDataSource == NULL ), Panic( EPostConditionViolation ));
475 //[ assert the invariant ]
476 __ASSERT_ALWAYS( Invariant(), Panic(EBadDataSourceRemoval));
481 Removes a data sink form the controller
485 @param aDataSink The sink that is to be removed. We donot
486 use this value, as we only support a single sink.
488 void CMMFAudioToneController::RemoveDataSinkL(MDataSink& /*aDataSink*/)
490 //[ assert the invariant ]
491 __ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForDataSinkRemoval) );
493 //[ precondition is that we have a data sink ]
495 User::Leave(KErrNotReady);
497 //[ the controller is in the stopped state ]
498 if(State() != EStopped)
499 User::Leave(KErrNotReady);
501 //[ remove the data sink from the controller and delete the format]
502 if(iSourceAndSinkAdded)
504 iMMFDevSound->Stop();
505 iSourceAndSinkAdded = EFalse;
508 delete iMMFDevSound; iMMFDevSound = NULL;
511 // [ assert postcondition we are stopped ]
512 __ASSERT_ALWAYS( (State() == EStopped), Panic(EPostConditionViolation) );
514 //[ assert postcondition the SourceAndSinkAdded is false ]
515 __ASSERT_ALWAYS( !iSourceAndSinkAdded, Panic( EPostConditionViolation ));
517 //[ assert the invariant ]
518 __ASSERT_ALWAYS( Invariant(), Panic(EBadDataSinkRemoval));
522 Handles a CustomCommand for the controller. This controller doesn't support Custom Commands
527 void CMMFAudioToneController::CustomCommand(TMMFMessage& aMessage)
529 //[ assert the invariant ]
530 __ASSERT_ALWAYS( Invariant(), Panic(ENotReadyForCustomCommand));
531 // [ We do not have any custom commands ]
532 aMessage.Complete(KErrNotSupported);
536 Configures Dev Sound, ready for playing.
540 void CMMFAudioToneController::NegotiateL()
543 Panic(EMMFAudioOutputDevSoundNotLoaded);
545 iMMFDevSound->InitializeL(*this, EMMFStateTonePlaying);
546 iMMFDevSound->SetPrioritySettings(iPrioritySettings);
548 //[ assert the invariant ]
549 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterNegotiate));
553 Set the priority settings that this controller should use to access Dev Sound
556 @param aPrioritySettings The requires priority settings
558 void CMMFAudioToneController::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
560 //[ assert the invariant ]
561 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetPriority));
563 //[ assert the precondition ]
564 if(State() != EStopped)
566 ASSERT(EFalse); // used to leave here with KErrNotReady
570 //[ update the priority settings of the controller]
571 iPrioritySettings = aPrioritySettings;
575 iMMFDevSound->SetPrioritySettings(iPrioritySettings);
578 __ASSERT_ALWAYS( Invariant(), Panic(EBadPriorityState));
584 This method is called by DevSound after initialization, indicating that it has completed and
585 whether there was an error
588 @param aError the error supplied by Dev Sound
590 void CMMFAudioToneController::InitializeComplete(TInt aError)
592 //[ assert the state is EPriming ]
593 __ASSERT_ALWAYS( ( State() == EPriming ), Panic( EBadState ));
594 __ASSERT_ALWAYS( iMessage, Panic( ENoMessageToProcess ));
596 if(aError != KErrNone)
598 SetState( EStopped );
599 iMessage->Complete(aError);
604 iMessage->Complete(aError);
605 iIsResumeSupported = iMMFDevSound->IsResumeSupported();
611 // [ assert the invariant]
612 __ASSERT_ALWAYS( Invariant(), Panic( EBadInitializeState ) );
617 This method is called by DevSound after it has finished playing a tone sequence, indicating
618 whether there was an error
621 @param aError the error supplied by DevSound
623 void CMMFAudioToneController::ToneFinished(TInt aError)
625 // NB KErrInUse, KErrDied OR KErrAccessDenied may be returned
626 // to indicate that the sound device is in use by another higher
628 if (aError == KErrCancel || aError == KErrInUse ||
629 aError == KErrDied || aError == KErrAccessDenied)
632 if (aError == KErrUnderflow)
635 if (State() != EStopped)
637 iMMFDevSound->Stop();
638 SetState( EStopped );
641 //now send event to client...
643 event.iEventType = KMMFEventCategoryPlaybackComplete;
644 event.iErrorCode = aError;
645 DoSendEventToClient(event);
651 Called my DevSound to indicate we have been thrown off H/W by a higher priority
654 @param aEvent contains the reason we have been contacted by DevSound
656 void CMMFAudioToneController::SendEventToClient(const TMMFEvent& aEvent)
658 if(State() == EPlaying)
661 DoSendEventToClient(aEvent);
668 Sets the playback volume
671 @param aVolume the required volume
673 void CMMFAudioToneController::MapdSetVolumeL(TInt aVolume)
675 //[ assert the invariant ]
676 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetVolume));
678 // [ precondition is true for state
679 // we can set the volume in any state ]
681 //[ precondition we have a data sink ]
683 User::Leave(KErrNotReady);
686 // [ assert the precondition that aVolume is in range ]
687 TInt maxVolume = iMMFDevSound->MaxVolume();
688 if( ( aVolume < 0 ) || ( aVolume > maxVolume ))
689 User::Leave(KErrArgument);
691 //[ set the volume on the device ]
692 iMMFDevSound->SetVolume(aVolume);
694 //[ assert the post condition volume is equal to a volume]
695 TInt soundVolume = 0;
696 soundVolume = iMMFDevSound->Volume();
698 __ASSERT_ALWAYS( ( soundVolume == aVolume), Panic(EPostConditionViolation));
700 //[ assert the invariant ]
701 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterVolumeSet));
705 Gets the maximum level the playback volume can be set to
708 @param aMaxVolume contains the maximum volume setting
710 void CMMFAudioToneController::MapdGetMaxVolumeL(TInt& aMaxVolume)
712 // [ assert the invariant ]
713 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetMaxVolume));
715 //[ precondition we have a data sink ]
717 User::Leave(KErrNotReady);
719 //[ get the volume from the device ]
720 aMaxVolume = iMMFDevSound->MaxVolume();
722 //[ assert the invariant ]
723 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetMaxVolume));
729 Gets the current playback volume
732 @param aVolume the current volume
734 void CMMFAudioToneController::MapdGetVolumeL(TInt& aVolume)
736 // [ assert the invariant ]
737 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetVolume));
739 //[ precondition that we have a data sink ]
741 User::Leave(KErrNotReady);
743 aVolume = iMMFDevSound->Volume();
745 // [ assert precondition that the volume is in range
747 TInt aMaxVolume = iMMFDevSound->MaxVolume();
748 __ASSERT_ALWAYS( (aVolume <= aMaxVolume), Panic(EBadState));
749 __ASSERT_ALWAYS( (aVolume >= 0), Panic(EBadState));
751 // [ assert the invariant ]
752 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetVolume));
757 Sets the duration over which the volume should increase
760 @param aRampDuration the time over which the volume should ramp
762 void CMMFAudioToneController::MapdSetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration)
764 // [ assert the invariant ]
765 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToSetVolumeRamp));
767 //[ precondition that we have a data sink ]
769 User::Leave(KErrNotReady);
771 iMMFDevSound->SetVolumeRamp(aRampDuration);
773 //[ assert the invariant ]
774 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterSetVolumeRamp));
780 Sets the balance of the tone playback
783 @param aBalance the required balance level (KMMFBalanceMaxLeft <= aBalance <= KMMFBalanceMaxRight)
785 void CMMFAudioToneController::MapdSetBalanceL(TInt aBalance)
787 //[ assert the invariant ]
788 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateToSetBalance));
790 // [ precondition is that we have a data sink ]
792 User::Leave(KErrNotReady);
795 // [ separate out left and right balance ]
798 CalculateLeftRightBalance( left, right, aBalance );
800 //[ set the balance ]
801 iMMFDevSound->SetPlayBalanceL(left, right);
803 // [assert the post condition that the balance is set correctly]
804 TInt rightBalance = 0;
805 TInt leftBalance = 0;
806 iMMFDevSound->GetPlayBalanceL(leftBalance, rightBalance);
808 //[ assert post condition holds]
809 TBool postCondition = (( rightBalance == right) && ( leftBalance == left));
810 __ASSERT_ALWAYS( postCondition, Panic( EPostConditionViolation ) );
812 //[ assert the invariant ]
813 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateAfterSetBalance));
817 Converts the balance from a range to a left/right form.
819 Balance is provided to devsound using left and right levels, but supplied to the controller as a range
820 (KMMFBalanceMaxLeft --> KMMFBalanceMaxRight). This method converts the range into a left/right form
824 @param aLeft set to the left setting
825 @param aRight set to the right setting
826 @param aBalance the range required
828 void CMMFAudioToneController::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
830 // Check the balance is within limits & modify to min or max values if necessary
831 if (aBalance < KMMFBalanceMaxLeft)
832 aBalance = KMMFBalanceMaxLeft;
833 if (aBalance > KMMFBalanceMaxRight)
834 aBalance = KMMFBalanceMaxRight;
836 //[ Now separate percentage balances out from aBalance ]
837 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight);
838 aRight = 100 - aLeft;
840 //[ assert post condition that left and right are within range ]
841 __ASSERT_ALWAYS( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPostConditionViolation));
842 __ASSERT_ALWAYS( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPostConditionViolation));
847 Gets the balance of the tone playback
850 @param aBalance set to the current balance level (KMMFBalanceMaxLeft <= aBalance <= KMMFBalanceMaxRight)
852 void CMMFAudioToneController::MapdGetBalanceL(TInt& aBalance)
854 //[ assert the invariant ]
855 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateToGetBalance));
857 //[ precondition that we have a sink]
859 User::Leave(KErrNotReady);
862 TInt left = 50; // arbitrary values
864 iMMFDevSound->GetPlayBalanceL(left, right);
866 CalculateBalance( aBalance, left, right );
868 //[ assert the invariant ]
869 __ASSERT_ALWAYS( Invariant(), Panic(EBadStateAfterGetBalance));
874 Converts the balance from a left/right form to a range.
876 Balance is obtained from DevSound using left and right levels, but supplied to the client as a range
877 (KMMFBalanceMaxLeft --> KMMFBalanceMaxRight).
881 @param aLeft the current left setting
882 @param aRight current right setting
883 @param aBalance set to the balance range
885 void CMMFAudioToneController::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
887 //[ assert pre conditions ]
888 __ASSERT_ALWAYS( (( aLeft + aRight ) == 100 ), Panic( EBadArgument ));
889 __ASSERT_ALWAYS( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EBadArgument) );
890 __ASSERT_ALWAYS( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EBadArgument) );
892 aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight;
894 //[ assert post condition that aBalance is within limits ]
895 __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument));
903 The function validates a state transition from iState to aState and
904 returns ETrue if the transition is allowed.
907 @param TControllerState
908 @return Valid controller state or not
910 TBool CMMFAudioToneController::IsValidStateTransition( TControllerState aState ) const
912 TBool result = ETrue ;
913 //[ assert the precondition that aState is a valid State ]
914 __ASSERT_ALWAYS( IsValidState(aState), Panic( EBadArgument ) );
915 //[ assert the invariant that iState is a valid State ]
916 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateForTransition ));
918 // [ check the valid state transitions ]
919 // the only invalid transition is
920 // stopped to playing
921 if( ( iState == EStopped ) && ( aState == EPlaying ))
926 //[ assert the invariant that iState is a valid State ]
927 __ASSERT_ALWAYS( Invariant(), Panic( EBadStateAfterTransition ));
933 This function returns whether the invariant is valid
936 @return Is the class in a good condition
938 TBool CMMFAudioToneController::Invariant() const
940 //[ The invariant is for now defined
941 // as simply being in the correct state
942 return IsValidState( iState);
946 This function sets the state of the controller.
949 @return Whether ths state transition is valid
951 TBool CMMFAudioToneController::SetState(TControllerState aState)
953 TBool result = ETrue;
954 //[ assert the precondition that the state is a valid state ]
955 __ASSERT_ALWAYS( IsValidState( aState), Panic( EBadArgument ) );
956 //[ assert the invariant the current state is valid ]
957 __ASSERT_ALWAYS( Invariant(), Panic( EStateNotValid ) );
958 //[ only allow valid state transitions ]
959 if( IsValidStateTransition( aState ) )
961 //[ valid state transition set the state]
966 //[ invalid state transition return EFalse ]
969 // [ assert the invariant on the state ]
970 __ASSERT_ALWAYS( Invariant(), Panic( EBadState ));
976 checks whether a state is valid
979 @return Is the state a valid one
981 TBool CMMFAudioToneController::IsValidState( TControllerState aState ) const
983 TBool result = EFalse;
984 if(( aState >= EStopped ) && ( aState <= EPlaying ))
992 The function State returns the current state of the audio controller
995 @return State of the controller
997 CMMFAudioToneController::TControllerState CMMFAudioToneController::State() const
999 __ASSERT_ALWAYS( Invariant(), Panic( EBadState ) );
1006 * @param aRepeatNumberOfTimes
1007 * @param aTrailingSilence
1010 TInt CMMFAudioToneController::MapcSetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
1012 TInt err = KErrNone;
1015 return KErrNotReady;
1019 if(iMMFDevSound->QueryIgnoresUnderflow())
1021 iMMFDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence);
1025 err = KErrNotSupported;