sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: sl@0: #include "mmfclienttoneplayer.h" sl@0: using namespace ContentAccess; sl@0: enum TMmfMdaAudioToneUtility sl@0: { sl@0: EBadArgument, sl@0: EPostConditionViolation, sl@0: EPlayStartedCalledWithError sl@0: }; sl@0: sl@0: // declared in the recorder module sl@0: void Panic(TInt aPanicCode); sl@0: sl@0: /** sl@0: Creates a new instance of the tone player utility. sl@0: The default volume is set to MaxVolume() / 2. sl@0: sl@0: @param aObserver sl@0: A class to receive notifications from the tone player. sl@0: @param aServer sl@0: This parameter is no longer used and should be NULL. sl@0: sl@0: @return A pointer to the new audio tone player utility object. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* aServer /*= NULL*/) sl@0: { sl@0: return CMdaAudioToneUtility::NewL(aObserver, aServer, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality); sl@0: } sl@0: sl@0: /** sl@0: Creates a new instance of the tone player utility. sl@0: The default volume is set to MaxVolume() / 2. sl@0: sl@0: @param aObserver sl@0: A class to receive notifications from the tone player sl@0: @param aServer sl@0: This parameter is no longer used and should be NULL sl@0: @param aPriority sl@0: The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and sl@0: EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request. sl@0: @param aPref sl@0: The Priority Preference - an additional audio policy parameter. The suggested default is sl@0: EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional sl@0: values may be supported by given phones and/or platforms, but should not be depended upon by sl@0: portable code. sl@0: sl@0: @return A pointer to the new audio tone player utility object. sl@0: sl@0: @since 5.0 sl@0: sl@0: Note: The Priority Value and Priority Preference are used primarily when deciding what to do when sl@0: several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, sl@0: the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. sl@0: Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may sl@0: vary between different phones. Portable applications are advised not to assume any specific behaviour. sl@0: */ sl@0: EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/, sl@0: TInt aPriority /*= EMdaPriorityNormal*/, sl@0: TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/) sl@0: { sl@0: CMdaAudioToneUtility* self = new(ELeave) CMdaAudioToneUtility(); sl@0: CleanupStack::PushL(self); sl@0: self->iProperties = CMMFMdaAudioToneUtility::NewL(aObserver, NULL, aPriority, aPref); sl@0: CleanupStack::Pop(); //self sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: Destructor. Frees any resources held by the tone player sl@0: sl@0: @since 5.0 sl@0: */ sl@0: CMdaAudioToneUtility::~CMdaAudioToneUtility() sl@0: { sl@0: delete iProperties; sl@0: } sl@0: sl@0: /** sl@0: Returns the current state of the audio tone utility. sl@0: sl@0: @return The state of the audio tone utility. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: TMdaAudioToneUtilityState CMdaAudioToneUtility::State() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->State(); sl@0: } sl@0: sl@0: /** sl@0: Returns the maximum volume supported by the device. This is the maximum value which can be sl@0: passed to CMdaAudioToneUtility::SetVolume(). sl@0: sl@0: @return The maximum volume. This value is platform dependent but is always greater than or equal to one. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: TInt CMdaAudioToneUtility::MaxVolume() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->MaxVolume(); sl@0: } sl@0: sl@0: /** sl@0: Returns an integer representing the current volume of the audio device. sl@0: sl@0: @return The current volume. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: TInt CMdaAudioToneUtility::Volume() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->Volume(); sl@0: } sl@0: sl@0: /** sl@0: Changes the volume of the audio device. sl@0: sl@0: The volume can be changed before or during play and is effective sl@0: immediately. sl@0: sl@0: @param aVolume sl@0: The volume setting. This can be any value from zero to sl@0: the value returned by a call to sl@0: CMdaAudioToneUtility::MaxVolume(). sl@0: Setting a zero value mutes the sound. Setting the sl@0: maximum value results in the loudest possible sound. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::SetVolume(TInt aVolume) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetVolume(aVolume); sl@0: } sl@0: sl@0: /** sl@0: Changes the clients priority. sl@0: sl@0: @param aPriority sl@0: The Priority Value. sl@0: @param aPref sl@0: The Priority Preference. sl@0: sl@0: @see CMdaAudioToneUtility::NewL() sl@0: sl@0: @since 5.0 sl@0: sl@0: */ sl@0: void CMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetPriority(aPriority, aPref); sl@0: } sl@0: sl@0: /** sl@0: Changes the duration of DTMF tones, the gaps between DTMF tones and the sl@0: pauses. sl@0: sl@0: @param aToneLength sl@0: The duration of the DTMF tone in microseconds. sl@0: @param aToneOffLength sl@0: The gap between DTFM tones in microseconds. sl@0: @param aPauseLength sl@0: Pauses in microseconds sl@0: */ sl@0: void CMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength, sl@0: TTimeIntervalMicroSeconds32 aToneOffLength, sl@0: TTimeIntervalMicroSeconds32 aPauseLength) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength); sl@0: } sl@0: sl@0: /** sl@0: Sets the number of times the tone sequence is to be repeated during sl@0: the play operation. sl@0: sl@0: A period of silence can follow each playing of the tone sequence. The sl@0: tone sequence can be repeated indefinitely. sl@0: sl@0: @param aRepeatNumberOfTimes sl@0: The number of times the tone sequence, together with sl@0: the trailing silence, is to be repeated. If this is sl@0: set to KMdaRepeatForever, then the tone sl@0: sequence, together with the trailing silence, is sl@0: repeated indefinitely. The behaviour is undefined for values other than sl@0: KMdaRepeatForever, zero and positive. sl@0: @param aTrailingSilence sl@0: The time interval of the training silence. The behaviour is undefined sl@0: for values other than zero and positive. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes, sl@0: const TTimeIntervalMicroSeconds& aTrailingSilence) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence); sl@0: } sl@0: sl@0: /** sl@0: Defines the period over which the volume level is to rise smoothly sl@0: from nothing to the normal volume level. sl@0: sl@0: @param aRampDuration sl@0: The period over which the volume is to rise. A zero sl@0: value causes the tone to be played at the normal level sl@0: for the full duration of the playback. A value which sl@0: is longer than the duration of the tone sequence means sl@0: that the tone never reaches its normal volume level. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetVolumeRamp(aRampDuration); sl@0: } sl@0: sl@0: /** sl@0: Returns the number of available pre-defined tone sequences. sl@0: sl@0: @return The number of tone sequences. This value is implementation sl@0: dependent but is always greater than or equal to zero. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: TInt CMdaAudioToneUtility::FixedSequenceCount() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->FixedSequenceCount(); sl@0: } sl@0: sl@0: /** sl@0: Returns the name assigned to a specific pre-defined tone sequence. sl@0: sl@0: @param aSequenceNumber sl@0: The index identifying the specific pre-defined tone sequence. sl@0: Index values are relative to zero. This can be any value from sl@0: zero to the value returned by a call to FixedSequenceCount() - 1. sl@0: The function raises a panic if sequence number is not within this sl@0: range. sl@0: sl@0: @see CMMFDevSound::FixedSequenceName(TInt aSequenceNumber) sl@0: @see FixedSequenceCount() sl@0: sl@0: @return The name assigned to the tone sequence. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: const TDesC& CMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber) sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->FixedSequenceName(aSequenceNumber); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play a single tone. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation.The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aFrequency sl@0: The frequency (pitch) of the tone in Hz. sl@0: @param aDuration sl@0: The duration of the tone in microseconds. sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayTone(aFrequency, aDuration); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play a dual tone. sl@0: The generated tone consists of two sine waves of different sl@0: frequencies summed together. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aFrequencyOne sl@0: The first frequency (pitch) of the tone. sl@0: @param aFrequencyTwo sl@0: The second frequency (pitch) of the tone. sl@0: @param aDuration sl@0: The duration of the tone in microseconds. sl@0: sl@0: @since 7.0sy sl@0: */ sl@0: EXPORT_C void CMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayDualTone(aFrequencyOne, aFrequencyTwo, aDuration); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone utility player to play a DTMF (Dual-Tone sl@0: Multi-Frequency) string. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aDTMF sl@0: A descriptor containing the DTMF string. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayDTMFString(aDTMF); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play a tone sequence sl@0: contained in a descriptor. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aSequence sl@0: The descriptor containing the tone sequence. The sl@0: format of the data is unspecified but is expected to sl@0: be platform dependent. A device might support more sl@0: than one form of sequence data. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayDesSequence(aSequence); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play a tone sequence sl@0: contained in a file. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aFileName sl@0: The full path name of the file containing the tone sl@0: sequence. The format of the data is unspecified but is sl@0: expected to be platform dependent. A device might sl@0: support more than one form of sequence data. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayFileSequence(aFileName); sl@0: } sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play a tone sequence sl@0: contained in a file. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aFile sl@0: A handle to an open file containing the tone sl@0: sequence. The format of the data is unspecified but is sl@0: expected to be platform dependent. A device might sl@0: support more than one form of sequence data. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: EXPORT_C void CMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFile) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayFileSequence(aFile); sl@0: } sl@0: sl@0: sl@0: /** sl@0: Configures the audio tone player utility to play the specified sl@0: pre-defined tone sequence. sl@0: sl@0: This function is asynchronous. On completion, the observer callback sl@0: function MMdaAudioToneObserver::MatoPrepareComplete() is sl@0: called, indicating the success or failure of the configuration sl@0: operation. The configuration operation can be cancelled by calling sl@0: CMdaAudioToneUtility::CancelPrepare(). The configuration sl@0: operation cannot be started if a play operation is in progress. sl@0: sl@0: @param aSequenceNumber sl@0: An index into the set of pre-defined tone sequences. sl@0: This can be any value from zero to the value returned by a sl@0: call to FixedSequenceCount() - 1. sl@0: If the sequence number is not within this range, a panic will be sl@0: raised when Play() is called later. sl@0: sl@0: @see FixedSequenceCount() sl@0: @see CMMFDevSound::PlayFixedSequenceL(TInt aSequenceNumber) sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->PrepareToPlayFixedSequence(aSequenceNumber); sl@0: } sl@0: sl@0: /** sl@0: Cancels the configuration operation. sl@0: sl@0: The observer callback function sl@0: MMdaAudioToneObserver::MatoPrepareComplete() is not sl@0: called. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::CancelPrepare() sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->CancelPrepare(); sl@0: } sl@0: sl@0: /** sl@0: Plays the tone. sl@0: sl@0: The tone played depends on the current configuration.This function is sl@0: asynchronous. On completion, the observer callback function sl@0: MMdaAudioToneObserver::MatoPlayComplete() is called, sl@0: indicating the success or failure of the play operation.The play sl@0: operation can be cancelled by sl@0: calling CMdaAudioToneUtility::CancelPlay(). sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::Play() sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->Play(); sl@0: } sl@0: sl@0: EXPORT_C TInt CMdaAudioToneUtility::Pause() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->Pause(); sl@0: } sl@0: sl@0: EXPORT_C TInt CMdaAudioToneUtility::Resume() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->Resume(); sl@0: } sl@0: sl@0: /** sl@0: Cancels the tone playing operation. sl@0: sl@0: The observer callback sl@0: function MMdaAudioToneObserver::MatoPlayComplete() is not sl@0: called. sl@0: sl@0: @since 5.0 sl@0: */ sl@0: void CMdaAudioToneUtility::CancelPlay() sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->CancelPlay(); sl@0: } sl@0: sl@0: /** sl@0: Sets the stereo balance for playback. sl@0: sl@0: @param aBalance sl@0: The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight. sl@0: sl@0: @return An error code indicating if the function call was successful. KErrNone on success, otherwise sl@0: another of the system-wide error codes. sl@0: sl@0: @since 7.0s sl@0: */ sl@0: EXPORT_C void CMdaAudioToneUtility::SetBalanceL(TInt aBalance /*=KMMFBalanceCenter*/) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->SetBalanceL(aBalance); sl@0: } sl@0: sl@0: /** sl@0: * Returns The current playback balance.This function may not return the same value sl@0: * as passed to SetBalanceL depending on the internal implementation in sl@0: * the underlying components. sl@0: * sl@0: * @return The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight. sl@0: * sl@0: * @since 7.0s sl@0: */ sl@0: EXPORT_C TInt CMdaAudioToneUtility::GetBalanceL() sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->GetBalanceL(); sl@0: } sl@0: sl@0: /** sl@0: Retrieves a custom interface to the underlying device. sl@0: sl@0: @param aInterfaceId sl@0: The interface UID, defined with the custom interface. sl@0: sl@0: @return A pointer to the interface implementation, or NULL if the device does not sl@0: implement the interface requested. The return value must be cast to the sl@0: correct type by the user. sl@0: */ sl@0: EXPORT_C TAny* CMdaAudioToneUtility::CustomInterface(TUid aInterfaceId) sl@0: { sl@0: ASSERT(iProperties); sl@0: return iProperties->CustomInterface(aInterfaceId); sl@0: } sl@0: sl@0: EXPORT_C void CMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver) sl@0: { sl@0: ASSERT(iProperties); sl@0: iProperties->RegisterPlayStartCallback(aObserver); sl@0: } sl@0: sl@0: sl@0: sl@0: CMMFMdaAudioToneUtility* CMMFMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/, sl@0: TInt aPriority /*= EMdaPriorityNormal*/, sl@0: TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/) sl@0: sl@0: { sl@0: CMMFMdaAudioToneUtility* self = new(ELeave) CMMFMdaAudioToneUtility(aObserver, aPriority, aPref); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: sl@0: sl@0: CMMFMdaAudioToneUtility::CMMFMdaAudioToneUtility(MMdaAudioToneObserver& aCallback, TInt aPriority, TInt aPref) : sl@0: iCallback(aCallback) sl@0: { sl@0: iPrioritySettings.iPref = aPref; sl@0: iPrioritySettings.iPriority = aPriority; sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: iInitialized = EFalse; sl@0: iPlayCalled = EFalse; sl@0: sl@0: #ifdef _DEBUG sl@0: iPlayCalledBeforeInitialized = EFalse; sl@0: #endif sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::ConstructL() sl@0: { sl@0: iAsyncCallback = CMMFMdaAudioToneObserverCallback::NewL(*this, *this); sl@0: sl@0: iDevSound = CMMFDevSound::NewL(); sl@0: iDevSound->InitializeL(*this,EMMFStateTonePlaying); sl@0: sl@0: // In some implementations InitializeComplete() returns in the InitializeL() context, sl@0: // check the error sl@0: User::LeaveIfError(iInitializeState); sl@0: sl@0: iDevSound->SetPrioritySettings(iPrioritySettings); sl@0: SetVolume(MaxVolume()/2 ); // set the volume to an intermediate value sl@0: } sl@0: sl@0: CMMFMdaAudioToneUtility::~CMMFMdaAudioToneUtility() sl@0: { sl@0: delete iDevSound; sl@0: delete iAsyncCallback; sl@0: delete iToneConfig; sl@0: } sl@0: sl@0: sl@0: sl@0: void CMMFMdaAudioToneUtility::InitializeComplete(TInt aError) sl@0: { sl@0: #ifdef _DEBUG sl@0: __ASSERT_ALWAYS(!iPlayCalledBeforeInitialized, User::Panic(_L("PlayInitialized called before InitializeComplete"), 0)); sl@0: #endif sl@0: iInitialized = ETrue; sl@0: sl@0: if (iPlayCalled) sl@0: { sl@0: // Play() is called before InitializeComplete() sl@0: if (aError == KErrNone) sl@0: { sl@0: PlayAfterInitialized(); sl@0: } sl@0: else sl@0: { sl@0: // InitializeComplete() with error other than KErrNone sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: iAsyncCallback->MatoPlayComplete(aError); sl@0: } sl@0: iPlayCalled = EFalse; sl@0: } sl@0: iInitializeState = aError; sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::ToneFinished(TInt aError) sl@0: { sl@0: if (aError != KErrCancel) sl@0: { sl@0: if (aError == KErrUnderflow) sl@0: { sl@0: aError = KErrNone; sl@0: } sl@0: sl@0: iAsyncCallback->MatoPlayComplete(aError); sl@0: } sl@0: // else don't want to callback after a cancel sl@0: } sl@0: sl@0: sl@0: TMdaAudioToneUtilityState CMMFMdaAudioToneUtility::State() sl@0: { sl@0: return iState; sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::MaxVolume() sl@0: { sl@0: return iDevSound->MaxVolume(); sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::Volume() sl@0: { sl@0: return iDevSound->Volume(); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::SetVolume(TInt aVolume) sl@0: { sl@0: iDevSound->SetVolume(aVolume); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref) sl@0: { sl@0: iPrioritySettings.iPref = aPref; sl@0: iPrioritySettings.iPriority = aPriority; sl@0: iDevSound->SetPrioritySettings(iPrioritySettings); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength, sl@0: TTimeIntervalMicroSeconds32 aToneOffLength, sl@0: TTimeIntervalMicroSeconds32 aPauseLength) sl@0: { sl@0: iDevSound->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence) sl@0: { sl@0: iDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration) sl@0: { sl@0: iDevSound->SetVolumeRamp(aRampDuration); sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::FixedSequenceCount() sl@0: { sl@0: return iDevSound->FixedSequenceCount(); sl@0: } sl@0: sl@0: const TDesC& CMMFMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber) sl@0: { sl@0: return iDevSound->FixedSequenceName(aSequenceNumber); sl@0: } sl@0: sl@0: /** sl@0: * CalculateBalance sl@0: * @param aBalance sl@0: * @param aLeft sl@0: * @param aRight sl@0: * sl@0: * follows a simple straight line transformation sl@0: * y = m x + c sl@0: * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100 sl@0: * c = KMMFBalanceMaxRight sl@0: * by substitution sl@0: * when aLeft = 0 sl@0: * KMMFBalanceMaxRight = m * 0 + c sl@0: * c = KMMFBalanceMaxRight sl@0: * when aLeft = 100 sl@0: * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight sl@0: * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100 sl@0: */ sl@0: void CMMFMdaAudioToneUtility::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const sl@0: { sl@0: //[ assert pre conditions ] sl@0: __ASSERT_ALWAYS( (( aLeft + aRight ) == 100 ), Panic( EBadArgument )); sl@0: __ASSERT_ALWAYS( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EBadArgument) ); sl@0: __ASSERT_ALWAYS( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EBadArgument) ); sl@0: sl@0: aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight; sl@0: sl@0: //[ assert post condition that aBalance is within limits ] sl@0: __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument)); sl@0: sl@0: } sl@0: sl@0: sl@0: /** sl@0: * CalculateLeftRightBalance sl@0: * @param aLeft sl@0: * @param aRight sl@0: * @param aBalance sl@0: * Preconditions: sl@0: * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight) sl@0: * y = m x + c sl@0: * aLeft = m ( aBalance ) + c sl@0: * when aBalance = KMMFBalanceMaxLeft aLeft = 100 sl@0: * when aBalance = KMMFBalanceMaxRight aLeft = 0 sl@0: * 100 = m( KMMFBalanceMaxLeft ) + c sl@0: * 0 = m( KMMFBalanceMaxRight ) + c sl@0: * c = -(KMMFBalanceMaxRight) m sl@0: * 100 = m(KMMFBalanceMaxLeft ) - m(KMMFBalanceMaxRight) sl@0: * m = 100/(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: * c = -(KMMFBalanceMaxRight) * 100 /(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: * aLeft = ( aBalance - KMMFBalanceMaxRight ) * 100 /( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: */ sl@0: void CMMFMdaAudioToneUtility::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const sl@0: { sl@0: // [ assert precondition that aBalance is within limits ] sl@0: __ASSERT_ALWAYS( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EBadArgument)); sl@0: sl@0: //[ Now separate percentage balances out from aBalance ] sl@0: aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight); sl@0: aRight = 100 - aLeft; sl@0: sl@0: //[ assert post condition that left and right are within range ] sl@0: __ASSERT_ALWAYS( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPostConditionViolation)); sl@0: __ASSERT_ALWAYS( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPostConditionViolation)); sl@0: } sl@0: sl@0: sl@0: void CMMFMdaAudioToneUtility::SetBalanceL(TInt aBalance) sl@0: { sl@0: TInt left; sl@0: TInt right; sl@0: CalculateLeftRightBalance(left,right,aBalance); sl@0: iDevSound->SetPlayBalanceL(left,right); sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::GetBalanceL() sl@0: { sl@0: TInt left; sl@0: TInt right; sl@0: TInt balance; sl@0: iDevSound->GetPlayBalanceL(left, right); sl@0: CalculateBalance(balance,left,right); sl@0: return balance; sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFSimpleToneConfig::NewL(aFrequency, aDuration)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFDualToneConfig::NewL(aFrequencyOne, aFrequencyTwo, aDuration)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFDTMFStringToneConfig::NewL(aDTMF)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFDesSeqToneConfig::NewL(aSequence)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFileName) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFFileSeqToneConfig::NewL(aFileName)); sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: void CMMFMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber) sl@0: { sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: TRAPD(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(aSequenceNumber)); sl@0: iSequenceNumber = aSequenceNumber; sl@0: iAsyncCallback->MatoPrepareComplete(error); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::CancelPrepare() sl@0: { sl@0: // xxx - do we need to cancel the callback? What if the callback is actually calling back another error? Probably best not to cancel... sl@0: delete iToneConfig; sl@0: iToneConfig = NULL; sl@0: sl@0: if (iState == EMdaAudioToneUtilityPrepared) sl@0: { sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: } sl@0: // Cancel the AO sl@0: iAsyncCallback->Cancel(); sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::Pause() sl@0: { sl@0: // Handle scenario when Pause is called before playback has started sl@0: if (iState != EMdaAudioToneUtilityPlaying || (iState == EMdaAudioToneUtilityPlaying && !iInitialized)) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: sl@0: else if(! iDevSound->IsResumeSupported() || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: iDevSound->Pause(); sl@0: iState = EMdaAudioToneUtilityPaused; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CMMFMdaAudioToneUtility::Resume() sl@0: { sl@0: TInt err = KErrNone; sl@0: if (iState != EMdaAudioToneUtilityPaused) sl@0: { sl@0: err = KErrNotReady; sl@0: } sl@0: sl@0: else if( iDevSound->IsResumeSupported() == EFalse || iToneConfig->Type() != CMMFToneConfig::EMmfToneTypeFileSeq) sl@0: { sl@0: err = KErrNotSupported; sl@0: } sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: err = iDevSound->Resume(); sl@0: if(err == KErrNone) sl@0: { sl@0: iState = EMdaAudioToneUtilityPlaying; sl@0: } sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::Play() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: if ((iState == EMdaAudioToneUtilityPlaying) || (iState == EMdaAudioToneUtilityPaused) || iPlayCalled) sl@0: { sl@0: error = KErrInUse; sl@0: } sl@0: sl@0: if (!error) sl@0: { sl@0: if (!iToneConfig) sl@0: { sl@0: TRAP(error, iToneConfig = CMMFFixedSeqToneConfig::NewL(iSequenceNumber)); sl@0: } sl@0: } sl@0: // If there was an error, notify the client now. Otherwise, client will be notified when sl@0: // play has finished. sl@0: if (error) sl@0: { sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: iAsyncCallback->MatoPlayComplete(error); sl@0: } sl@0: sl@0: if (!error) sl@0: { sl@0: iState = EMdaAudioToneUtilityPlaying; sl@0: sl@0: if (iInitialized) sl@0: { sl@0: // Play() is called after InitializeComplete() sl@0: if (iInitializeState) sl@0: { sl@0: // InitializeComplete() with error other than KErrNone sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: iAsyncCallback->MatoPlayComplete(iInitializeState); sl@0: } sl@0: else sl@0: { sl@0: PlayAfterInitialized(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Play() is called before InitializeComplete() sl@0: iPlayCalled = ETrue; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::PlayAfterInitialized() sl@0: { sl@0: #ifdef _DEBUG sl@0: if (iInitialized == EFalse) sl@0: { sl@0: iPlayCalledBeforeInitialized = ETrue; sl@0: } sl@0: #endif sl@0: sl@0: TInt error = KErrNone; sl@0: switch (iToneConfig->Type()) sl@0: { sl@0: case CMMFToneConfig::EMmfToneTypeSimple: sl@0: { sl@0: CMMFSimpleToneConfig* c = STATIC_CAST(CMMFSimpleToneConfig*, iToneConfig); sl@0: TRAP(error, iDevSound->PlayToneL(c->Frequency(), c->Duration())); sl@0: break; sl@0: } sl@0: case CMMFToneConfig::EMmfToneTypeDual: sl@0: { sl@0: CMMFDualToneConfig* c = STATIC_CAST(CMMFDualToneConfig*, iToneConfig); sl@0: TRAP(error, iDevSound->PlayDualToneL(c->FrequencyOne(), c->FrequencyTwo(), c->Duration())); sl@0: break; sl@0: } sl@0: case CMMFToneConfig::EMmfToneTypeDTMF: sl@0: { sl@0: CMMFDTMFStringToneConfig* c = STATIC_CAST(CMMFDTMFStringToneConfig*, iToneConfig); sl@0: TRAP(error, iDevSound->PlayDTMFStringL(c->DTMF())); sl@0: break; sl@0: } sl@0: case CMMFToneConfig::EMmfToneTypeDesSeq: sl@0: { sl@0: CMMFDesSeqToneConfig* c = STATIC_CAST(CMMFDesSeqToneConfig*, iToneConfig); sl@0: TRAP(error, iDevSound->PlayToneSequenceL(c->DesSeq())); sl@0: break; sl@0: } sl@0: case CMMFToneConfig::EMmfToneTypeFileSeq: sl@0: { sl@0: CMMFFileSeqToneConfig* c = STATIC_CAST(CMMFFileSeqToneConfig*, iToneConfig); sl@0: sl@0: // check we have rights to play sl@0: TRAP(error, c->ExecuteIntentL()); sl@0: sl@0: // if we have rights then go ahead and play sl@0: if (error == KErrNone) sl@0: { sl@0: TRAP(error, iDevSound->PlayToneSequenceL(c->FileSeq())); sl@0: } sl@0: sl@0: break; sl@0: } sl@0: case CMMFToneConfig::EMmfToneTypeFixedSeq: sl@0: { sl@0: CMMFFixedSeqToneConfig* c = STATIC_CAST(CMMFFixedSeqToneConfig*, iToneConfig); sl@0: TRAP(error, iDevSound->PlayFixedSequenceL(c->SequenceNumber())); sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Panic(KMMFMdaAudioToneUtilityPanicCategory, EMMFMdaAudioToneUtilityBadToneConfig); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: // If there was an error, notify the client now. Otherwise, client will be notified when sl@0: // play has finished. sl@0: if (error) sl@0: { sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: iAsyncCallback->MatoPlayComplete(error); sl@0: } sl@0: else sl@0: { sl@0: if(iPlayStartObserver) sl@0: { sl@0: iAsyncCallback->MatoPlayStarted(KErrNone); sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::CancelPlay() sl@0: { sl@0: iDevSound->Stop(); sl@0: sl@0: if(iState == EMdaAudioToneUtilityPlaying || iState == EMdaAudioToneUtilityPaused) sl@0: { sl@0: iState = EMdaAudioToneUtilityPrepared; sl@0: } sl@0: // Cancel the AO sl@0: iAsyncCallback->Cancel(); sl@0: iPlayCalled = EFalse; sl@0: } sl@0: sl@0: sl@0: void CMMFMdaAudioToneUtility::SendEventToClient(const TMMFEvent& /*aEvent*/) sl@0: { sl@0: if(iState == EMdaAudioToneUtilityPlaying) sl@0: { sl@0: iState = EMdaAudioToneUtilityPrepared; sl@0: } sl@0: sl@0: iAsyncCallback->MatoPlayComplete(KErrInUse); sl@0: } sl@0: sl@0: sl@0: void CMMFMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver) sl@0: { sl@0: iPlayStartObserver = &aObserver; sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::MatoPrepareComplete(TInt aError) sl@0: { sl@0: if (!aError) sl@0: { sl@0: iState = EMdaAudioToneUtilityPrepared; sl@0: } sl@0: else sl@0: { sl@0: iState = EMdaAudioToneUtilityNotReady; sl@0: } sl@0: sl@0: iCallback.MatoPrepareComplete(aError); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::MatoPlayComplete(TInt aError) sl@0: { sl@0: iState = EMdaAudioToneUtilityPrepared; sl@0: iCallback.MatoPlayComplete(aError); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneUtility::MatoPlayStarted(TInt aError) sl@0: { sl@0: __ASSERT_DEBUG(aError==KErrNone, Panic(EPlayStartedCalledWithError)); sl@0: sl@0: // Not always there is an observer registered sl@0: if(iPlayStartObserver) sl@0: { sl@0: iPlayStartObserver->MatoPlayStarted(aError); sl@0: } sl@0: } sl@0: sl@0: // CustomInferface - just pass on to DevSound. sl@0: TAny* CMMFMdaAudioToneUtility::CustomInterface(TUid aInterfaceId) sl@0: { sl@0: return iDevSound->CustomInterface(aInterfaceId); sl@0: } sl@0: sl@0: sl@0: CMMFMdaAudioToneObserverCallback* CMMFMdaAudioToneObserverCallback::NewL(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback) sl@0: { sl@0: return new(ELeave) CMMFMdaAudioToneObserverCallback(aCallback, aPlayStartCallback); sl@0: } sl@0: sl@0: CMMFMdaAudioToneObserverCallback::CMMFMdaAudioToneObserverCallback(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback) : sl@0: CActive(CActive::EPriorityHigh), sl@0: iCallback(aCallback), sl@0: iPlayStartCallback(aPlayStartCallback) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CMMFMdaAudioToneObserverCallback::~CMMFMdaAudioToneObserverCallback() sl@0: { sl@0: Cancel(); sl@0: } sl@0: sl@0: void CMMFMdaAudioToneObserverCallback::MatoPrepareComplete(TInt aError) sl@0: { sl@0: if(!IsActive()) sl@0: { sl@0: iAction = EPrepareComplete; sl@0: iErrorCode = aError; sl@0: sl@0: TRequestStatus* s = &iStatus; sl@0: SetActive(); sl@0: User::RequestComplete(s, KErrNone); sl@0: } sl@0: else sl@0: { sl@0: // Since the default granularity is 8, failing of Append() is unusual, hence ignoring the return err. sl@0: iCallBackQueue.Append(EPrepareComplete); sl@0: iCallBackQueueError.Append(aError); sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneObserverCallback::MatoPlayComplete(TInt aError) sl@0: { sl@0: if(!IsActive()) sl@0: { sl@0: iAction = EPlayComplete; sl@0: iErrorCode = aError; sl@0: sl@0: TRequestStatus* s = &iStatus; sl@0: SetActive(); sl@0: User::RequestComplete(s, KErrNone); sl@0: } sl@0: else sl@0: { sl@0: iCallBackQueue.Append(EPlayComplete); sl@0: iCallBackQueueError.Append(aError); sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneObserverCallback::MatoPlayStarted(TInt aError) sl@0: { sl@0: if(!IsActive()) sl@0: { sl@0: iAction = EPlayStarted; sl@0: iErrorCode = aError; sl@0: sl@0: TRequestStatus* s = &iStatus; sl@0: SetActive(); sl@0: User::RequestComplete(s, KErrNone); sl@0: } sl@0: else sl@0: { sl@0: iCallBackQueue.Append(EPlayStarted); sl@0: iCallBackQueueError.Append(aError); sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneObserverCallback::RunL() sl@0: { sl@0: switch (iAction) sl@0: { sl@0: case EPrepareComplete: sl@0: { sl@0: iCallback.MatoPrepareComplete(iErrorCode); sl@0: break; sl@0: } sl@0: case EPlayComplete: sl@0: { sl@0: iCallback.MatoPlayComplete(iErrorCode); sl@0: break; sl@0: } sl@0: case EPlayStarted: sl@0: iPlayStartCallback.MatoPlayStarted(iErrorCode); sl@0: break; sl@0: } sl@0: if(iCallBackQueue.Count() > 0 & !IsActive() ) sl@0: { sl@0: iAction = TMMFAudioToneObserverCallbackAction(iCallBackQueue[0]); sl@0: iCallBackQueue.Remove(0); sl@0: iErrorCode = iCallBackQueueError[0]; sl@0: iCallBackQueueError.Remove(0); sl@0: sl@0: TRequestStatus* s = &iStatus; sl@0: User::RequestComplete(s, KErrNone); sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: void CMMFMdaAudioToneObserverCallback::DoCancel() sl@0: { sl@0: //nothing to cancel sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: // Tone config classes sl@0: sl@0: // Simple Tone sl@0: CMMFToneConfig* CMMFSimpleToneConfig::NewL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFSimpleToneConfig(aFrequency, aDuration)); sl@0: } sl@0: sl@0: CMMFSimpleToneConfig::CMMFSimpleToneConfig(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration) : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeSimple), sl@0: iFrequency(aFrequency), sl@0: iDuration(aDuration) sl@0: { sl@0: } sl@0: sl@0: CMMFSimpleToneConfig::~CMMFSimpleToneConfig() sl@0: { sl@0: } sl@0: sl@0: TInt CMMFSimpleToneConfig::Frequency() sl@0: { sl@0: return iFrequency; sl@0: } sl@0: sl@0: const TTimeIntervalMicroSeconds& CMMFSimpleToneConfig::Duration() sl@0: { sl@0: return iDuration; sl@0: } sl@0: sl@0: sl@0: // Dual Tone sl@0: CMMFToneConfig* CMMFDualToneConfig::NewL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) sl@0: { sl@0: return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFDualToneConfig(aFrequencyOne, aFrequencyTwo, aDuration)); sl@0: } sl@0: sl@0: CMMFDualToneConfig::CMMFDualToneConfig(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration) : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDual), sl@0: iFrequencyOne(aFrequencyOne), sl@0: iFrequencyTwo(aFrequencyTwo), sl@0: iDuration(aDuration) sl@0: { sl@0: } sl@0: sl@0: CMMFDualToneConfig::~CMMFDualToneConfig() sl@0: { sl@0: } sl@0: sl@0: TInt CMMFDualToneConfig::FrequencyOne() sl@0: { sl@0: return iFrequencyOne; sl@0: } sl@0: sl@0: TInt CMMFDualToneConfig::FrequencyTwo() sl@0: { sl@0: return iFrequencyTwo; sl@0: } sl@0: sl@0: const TTimeIntervalMicroSeconds& CMMFDualToneConfig::Duration() sl@0: { sl@0: return iDuration; sl@0: } sl@0: sl@0: sl@0: CMMFToneConfig* CMMFDTMFStringToneConfig::NewL(const TDesC& aDTMF) sl@0: { sl@0: CMMFDTMFStringToneConfig* s = new(ELeave) CMMFDTMFStringToneConfig; sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(aDTMF); sl@0: CleanupStack::Pop(); sl@0: return STATIC_CAST(CMMFToneConfig*, s); sl@0: } sl@0: sl@0: CMMFDTMFStringToneConfig::CMMFDTMFStringToneConfig() : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDTMF) sl@0: { sl@0: } sl@0: sl@0: LOCAL_C void validateDTMFL(const TDesC& aDTMF) sl@0: // sl@0: // Validate that the supplied DTMf string contains only playable characters sl@0: // sl@0: { sl@0: TInt stringLength = aDTMF.Length(); sl@0: TChar ch; sl@0: for (TInt index = 0; index < stringLength ; index++) sl@0: { sl@0: ch = aDTMF[index]; sl@0: if (!ch.IsDigit() && !ch.IsHexDigit() && !ch.IsSpace() && sl@0: (ch != '*') && (ch != '#') && (ch != ',')) sl@0: { sl@0: User::Leave(KErrArgument); // Bad DTMF string sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CMMFDTMFStringToneConfig::ConstructL(const TDesC& aDTMF) sl@0: { sl@0: validateDTMFL(aDTMF); sl@0: iDTMF = aDTMF.AllocL(); sl@0: } sl@0: sl@0: CMMFDTMFStringToneConfig::~CMMFDTMFStringToneConfig() sl@0: { sl@0: delete iDTMF; sl@0: } sl@0: sl@0: const TDesC& CMMFDTMFStringToneConfig::DTMF() sl@0: { sl@0: return *iDTMF; sl@0: } sl@0: sl@0: sl@0: CMMFToneConfig* CMMFDesSeqToneConfig::NewL(const TDesC8& aDesSeq) sl@0: { sl@0: CMMFDesSeqToneConfig* s = new(ELeave) CMMFDesSeqToneConfig; sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(aDesSeq); sl@0: CleanupStack::Pop(); sl@0: return STATIC_CAST(CMMFToneConfig*, s); sl@0: } sl@0: sl@0: CMMFDesSeqToneConfig::CMMFDesSeqToneConfig() : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeDesSeq) sl@0: { sl@0: } sl@0: sl@0: void CMMFDesSeqToneConfig::ConstructL(const TDesC8& aDesSeq) sl@0: { sl@0: iDesSeq = aDesSeq.AllocL(); sl@0: } sl@0: sl@0: CMMFDesSeqToneConfig::~CMMFDesSeqToneConfig() sl@0: { sl@0: delete iDesSeq; sl@0: } sl@0: sl@0: const TDesC8& CMMFDesSeqToneConfig::DesSeq() sl@0: { sl@0: return *iDesSeq; sl@0: } sl@0: sl@0: sl@0: CMMFToneConfig* CMMFFileSeqToneConfig::NewL(const TDesC& aFileSeq) sl@0: { sl@0: CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig; sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(aFileSeq); sl@0: CleanupStack::Pop(); sl@0: return STATIC_CAST(CMMFToneConfig*, s); sl@0: } sl@0: sl@0: CMMFFileSeqToneConfig::CMMFFileSeqToneConfig() : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFileSeq) sl@0: { sl@0: } sl@0: sl@0: void CMMFFileSeqToneConfig::ConstructL(const TDesC& aFileSeq) sl@0: { sl@0: // get access to DRM content through filename sl@0: iCAFContent = CContent::NewL(aFileSeq); sl@0: sl@0: // open the CAF source with play intent sl@0: iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject); sl@0: sl@0: // read into a descriptor sl@0: TInt dataSize = 0; sl@0: iCAFData->DataSizeL(dataSize); sl@0: sl@0: iDesSeq = HBufC8::NewL(dataSize); sl@0: TPtr8 desSeqPtr = iDesSeq->Des(); sl@0: iCAFData->Read(desSeqPtr); sl@0: } sl@0: sl@0: sl@0: sl@0: CMMFToneConfig* CMMFFileSeqToneConfig::NewL(RFile& aFile) sl@0: { sl@0: CMMFFileSeqToneConfig* s = new(ELeave) CMMFFileSeqToneConfig; sl@0: CleanupStack::PushL(s); sl@0: s->ConstructL(aFile); sl@0: CleanupStack::Pop(); sl@0: return STATIC_CAST(CMMFToneConfig*, s); sl@0: } sl@0: sl@0: sl@0: void CMMFFileSeqToneConfig::ConstructL(RFile& aFile) sl@0: { sl@0: // get DRM access to file handle sl@0: iCAFContent = CContent::NewL(aFile); sl@0: sl@0: // open the CAF source with play intent sl@0: iCAFData = iCAFContent->OpenContentL(ContentAccess::EPlay, KDefaultContentObject); sl@0: sl@0: // read into a descriptor sl@0: TInt dataSize = 0; sl@0: iCAFData->DataSizeL(dataSize); sl@0: sl@0: iDesSeq = HBufC8::NewL(dataSize); sl@0: TPtr8 desSeqPtr = iDesSeq->Des(); sl@0: iCAFData->Read(desSeqPtr); sl@0: } sl@0: sl@0: sl@0: CMMFFileSeqToneConfig::~CMMFFileSeqToneConfig() sl@0: { sl@0: delete iCAFData; sl@0: iCAFData = NULL; sl@0: sl@0: delete iCAFContent; sl@0: iCAFContent = NULL; sl@0: sl@0: delete iDesSeq; sl@0: } sl@0: sl@0: const TDesC8& CMMFFileSeqToneConfig::FileSeq() sl@0: { sl@0: return *iDesSeq; sl@0: } sl@0: sl@0: void CMMFFileSeqToneConfig::ExecuteIntentL() sl@0: { sl@0: if (iCAFData) sl@0: { sl@0: User::LeaveIfError(iCAFData->ExecuteIntent(ContentAccess::EPlay)); sl@0: } sl@0: } sl@0: sl@0: CMMFToneConfig* CMMFFixedSeqToneConfig::NewL(TInt aSeqNo) sl@0: { sl@0: return STATIC_CAST(CMMFToneConfig*, new(ELeave) CMMFFixedSeqToneConfig(aSeqNo)); sl@0: } sl@0: sl@0: CMMFFixedSeqToneConfig::CMMFFixedSeqToneConfig(TInt aSeqNo) : sl@0: CMMFToneConfig(CMMFToneConfig::EMmfToneTypeFixedSeq), sl@0: iSequenceNumber(aSeqNo) sl@0: { sl@0: } sl@0: sl@0: CMMFFixedSeqToneConfig::~CMMFFixedSeqToneConfig() sl@0: { sl@0: } sl@0: sl@0: TInt CMMFFixedSeqToneConfig::SequenceNumber() sl@0: { sl@0: return iSequenceNumber; sl@0: }