tactilefeedback/tactilefeedbackresolver/plugins/tactiletoneplugin/src/tactiletoneplayer.cpp
changeset 0 d54f32e146dd
child 12 63c33341dc19
child 15 8c57b70b4bf3
equal deleted inserted replaced
-1:000000000000 0:d54f32e146dd
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class for producing audio tone feedback.
       
    15 * Part of:      Tactile Feedback.
       
    16 *
       
    17 */
       
    18 
       
    19 #include <ecom/implementationproxy.h>
       
    20 #include <centralrepository.h>
       
    21 #include <audiopreference.h>
       
    22 #include <profileinternal.hrh>
       
    23 #include <MProfileEngine.h>
       
    24 #include <MProfile.h>
       
    25 #include <MProfileExtraSettings.h>
       
    26 #include <MProfileFeedbackSettings.h>
       
    27 #include <CProfileChangeNotifyHandler.h>
       
    28 
       
    29 #include "tactilefeedbackprivatecrkeys.h"
       
    30 #include "tactilefeedbacktrace.h"
       
    31 
       
    32 #include "tactiletoneplayer.h"
       
    33 #include "OstTraceDefinitions.h"
       
    34 #ifdef OST_TRACE_COMPILER_IN_USE
       
    35 #include "tactiletoneplayerTraces.h"
       
    36 #endif
       
    37 
       
    38 
       
    39 // ======== MEMBER FUNCTIONS ========
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 //  Constructor.
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 CTactileTonePlayer::CTactileTonePlayer( CRepository& aRepository ):
       
    46     iRepository(aRepository)
       
    47     {
       
    48     }
       
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // 2nd phase constructor.
       
    52 // ---------------------------------------------------------------------------
       
    53 //
       
    54 void CTactileTonePlayer::ConstructL()
       
    55     {
       
    56     TRACE("CTactileTonePlayer::ConstructL - Begin");    
       
    57     iMdaAudioToneUtility = CMdaAudioToneUtility::NewL( 
       
    58         *this,
       
    59         NULL,
       
    60         KAudioPriorityKeyPress,
       
    61         TMdaPriorityPreference( KAudioPrefKeyPressNonDTMF ) );
       
    62 
       
    63     User::LeaveIfError( iRepository.Get( KTactileFeedbackAudioVolume, 
       
    64                                          iAudioLevel ) );
       
    65 
       
    66     // As a fix to EAKH-7LKANT, we're temporarily reading volume level
       
    67     // settings from profiles engine
       
    68     InitializeProfilesEngineL();
       
    69                                          
       
    70     if ( iAudioLevel > EProfileAudioFeedbackLevel3 )
       
    71         {
       
    72         User::Leave( KErrGeneral );
       
    73         }
       
    74   
       
    75     ReadSettings();
       
    76     
       
    77     iMdaAudioToneUtility->PrepareToPlayTone(
       
    78         iSoundParams[0].iFrequency,
       
    79         iSoundParams[0].iDuration );
       
    80         
       
    81     iCenRepNotifier = CCenRepNotifyHandler::NewL( *this, 
       
    82                                                   iRepository, 
       
    83                                                   CCenRepNotifyHandler::EIntKey,
       
    84                                                   KTactileFeedbackAudioVolume );
       
    85     iCenRepNotifier->StartListeningL();         
       
    86     TRACE("CTactileTonePlayer::ConstructL - End");        
       
    87     }
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // 2-phased constructor.
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 CTactileTonePlayer* CTactileTonePlayer::NewL( CRepository& aRepository )
       
    94     {
       
    95     TRACE("CTactileTonePlayer::NewL - Begin");    
       
    96     CTactileTonePlayer* self = new ( ELeave ) CTactileTonePlayer(aRepository);
       
    97     CleanupStack::PushL( self );
       
    98     self->ConstructL();
       
    99     CleanupStack::Pop( self );
       
   100     TRACE("CTactileTonePlayer::NewL - End");    
       
   101     return self;
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------------
       
   105 // Destructor.
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 CTactileTonePlayer::~CTactileTonePlayer()
       
   109     {
       
   110     if( iProfileEng )
       
   111         {
       
   112         iProfileEng->Release();
       
   113         iProfileEng = NULL;
       
   114         }
       
   115     delete iProfileHandler;
       
   116     delete iCenRepNotifier;
       
   117     delete iMdaAudioToneUtility;
       
   118     iSoundParams.Close();
       
   119     }
       
   120 
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // From class CTactilePlayer
       
   124 //
       
   125 // Here we first check if we are ready to play, and then either play
       
   126 // sound immediately (if loaded parameters are correct), or then load
       
   127 // the proper parameters in case this feedback type is different than
       
   128 // the previously played one.
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 TInt CTactileTonePlayer::PlayFeedback( TTouchLogicalFeedback aFeedback )
       
   132     {
       
   133     TRACE("CTactileTonePlayer::PlayFeedback- Begin");
       
   134     if ( iState == ETactileToneReady )
       
   135         {
       
   136         TInt effectIndex(0);
       
   137         
       
   138         switch ( aFeedback )
       
   139             {
       
   140             case ETouchFeedbackBasic:               // flow through
       
   141             case ETouchFeedbackBasicButton:         // flow through
       
   142             case ETouchFeedbackList:                // flow through
       
   143             case ETouchFeedbackBoundaryList:        // flow through
       
   144             case ETouchFeedbackSlider:              // flow through
       
   145             case ETouchFeedbackEdit:                // flow through
       
   146             case ETouchFeedbackSensitiveInput:
       
   147             case ETouchFeedbackLineSelection:       // flow through
       
   148             case ETouchFeedbackBlankSelection:      // flow through
       
   149             case ETouchFeedbackTextSelection:       // flow through
       
   150             case ETouchFeedbackEmptyLineSelection:  // flow through
       
   151             case ETouchFeedbackTab:                 // flow through
       
   152             case ETouchFeedbackPopUp:               // flow through
       
   153             case ETouchFeedbackIncreasingPopUp:     // flow through
       
   154             case ETouchFeedbackDecreasingPopUp:     // flow through
       
   155             case ETouchFeedbackFlick:               // flow through
       
   156             case ETouchFeedbackCheckbox:            // flow through
       
   157             case ETouchFeedbackCharacterInputButton:
       
   158             case ETouchFeedbackMultiTouchRecognized:
       
   159                 effectIndex = 0;
       
   160                 break;
       
   161             case ETouchFeedbackSensitive:           // flow through
       
   162             case ETouchFeedbackSensitiveButton:     // flow through
       
   163             case ETouchFeedbackSensitiveList:      
       
   164                 effectIndex = 1;                    
       
   165                 break;                              
       
   166             default:                                
       
   167                 effectIndex = 0;                    
       
   168                 break;                              
       
   169             }                                       
       
   170                                                     
       
   171         // Check that we have valid effect index    
       
   172         if ( effectIndex < iSoundParams.Count() &&
       
   173              iAudioLevel != EProfileAudioFeedbackOff )
       
   174             {
       
   175             if ( effectIndex == iCurrentEffectIndex )
       
   176                 {
       
   177                 // Play the sound immediately.
       
   178                 OstTrace0( TACTILE_PERFORMANCE, TACTILE_PLAY_AUDIO_TONE_FEEDBACK_1, "e_TACTILE_PLAY_AUDIO_TONE_FEEDBACK 1");
       
   179                                 
       
   180                 iMdaAudioToneUtility->Play(); 
       
   181 
       
   182                 OstTrace0( TACTILE_PERFORMANCE, TACTILE_PLAY_AUDIO_TONE_FEEDBACK_0, "e_TACTILE_PLAY_AUDIO_TONE_FEEDBACK 0");
       
   183         
       
   184                 iState = ETactileTonePlaying;
       
   185                 }
       
   186             else
       
   187                 {      
       
   188                 // Load new parameters.          
       
   189                 iMdaAudioToneUtility->PrepareToPlayTone(
       
   190                     iSoundParams[effectIndex].iFrequency,
       
   191                     iSoundParams[effectIndex].iDuration );
       
   192 
       
   193                 iCurrentEffectIndex = effectIndex;
       
   194 
       
   195                 iState = ETactileTonePlayPending;
       
   196                 }
       
   197             }
       
   198         }
       
   199     TRACE("CTactileTonePlayer::PlayFeedback- End");
       
   200     return KErrNone;
       
   201     }
       
   202     
       
   203 // ---------------------------------------------------------------------------
       
   204 // 
       
   205 // 
       
   206 // ---------------------------------------------------------------------------
       
   207 //    
       
   208 TInt CTactileTonePlayer::PlayPreviewFeedback( TInt aLevel, 
       
   209                                              TTouchLogicalFeedback aFeedback )
       
   210     {
       
   211     TRACE("CTactileTonePlayer::PlayPreviewFeedback - Begin");
       
   212     TInt ret( KErrArgument );
       
   213     
       
   214     if ( aLevel > EProfileAudioFeedbackOff  &&
       
   215          aLevel <= EProfileAudioFeedbackLevel3 )
       
   216         {
       
   217         iOriginalLevel = iAudioLevel;
       
   218         iAudioLevel = aLevel;
       
   219         ReadSettings();    
       
   220         iCurrentEffectIndex = KErrNotFound;
       
   221         iPlayPreview = ETrue;
       
   222         ret = PlayFeedback( aFeedback );
       
   223         }    
       
   224     
       
   225     TRACE("CTactileTonePlayer::PlayPreviewFeedback - End");
       
   226     return ret;
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // From class MMdaAudioToneObserver.
       
   231 // 
       
   232 // If initialization was succesfull, then we set the volume according
       
   233 // to current effect, and after that either start to play (in case we
       
   234 // have a pending play request), or just set ourselves to ready state.
       
   235 //
       
   236 // If initialization failed, then we set ourselves to error state. 
       
   237 // In practice this means that no sounds will be played at all.
       
   238 // ---------------------------------------------------------------------------
       
   239 //
       
   240 void CTactileTonePlayer::MatoPrepareComplete( TInt aError )
       
   241     {
       
   242     if ( aError == KErrNone )
       
   243         {      
       
   244         if ( iCurrentEffectIndex < iSoundParams.Count() )
       
   245             {
       
   246             iMdaAudioToneUtility->SetVolume( 
       
   247                     iSoundParams[iCurrentEffectIndex].iVolume ); 
       
   248             }
       
   249         if ( iState == ETactileTonePlayPending )
       
   250             {
       
   251             iMdaAudioToneUtility->Play(); 
       
   252             
       
   253             if ( iPlayPreview )
       
   254                 {
       
   255                 iPlayPreview = EFalse;
       
   256                 iAudioLevel = iOriginalLevel;
       
   257                 ReadSettings();    
       
   258                 iCurrentEffectIndex = KErrNotFound;                
       
   259                 }
       
   260             iState = ETactileTonePlaying;            
       
   261             }
       
   262         else
       
   263             {
       
   264             iState = ETactileToneReady;                    
       
   265             }        
       
   266         }
       
   267     else
       
   268         {
       
   269         iState = ETactileToneError;
       
   270         }    
       
   271     }
       
   272 
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // From class MMdaAudioToneObserver.
       
   276 // 
       
   277 // Any errors are ignored, because they are most likely caused by
       
   278 // override of higher priority client.
       
   279 // ---------------------------------------------------------------------------
       
   280 //
       
   281 void CTactileTonePlayer::MatoPlayComplete( TInt /*aError*/ )
       
   282     {
       
   283     iState = ETactileToneReady;
       
   284     }
       
   285 
       
   286 
       
   287 // ---------------------------------------------------------------------------
       
   288 // Read all audio configuration options (frequency, duration and volume)
       
   289 // for each logical feedback into array according to current feedback level, 
       
   290 // so that they can conveniently be used when feedback needs to be played.
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 void CTactileTonePlayer::ReadSettings()
       
   294     {
       
   295     TRACE("CTactileTonePlayer::ReadSettingsL- Begin");    
       
   296     TTactileSoundParams basicParams;
       
   297     basicParams.iFrequency = 0;
       
   298     basicParams.iDuration   = TTimeIntervalMicroSeconds( 0 );
       
   299     basicParams.iVolume    = 0;
       
   300     
       
   301     TTactileSoundParams sensitiveParams = basicParams;
       
   302     
       
   303     TInt basicDuration = 0;
       
   304     TInt sensitiveDuration = 0;
       
   305     
       
   306     if ( iAudioLevel == EProfileAudioFeedbackLevel1 )
       
   307         {
       
   308         // Read settings for ETouchFeedbackBasic, level 1
       
   309         iRepository.Get( KTactileAudioToneFreqBasicLevel1,     
       
   310                          basicParams.iFrequency );
       
   311         iRepository.Get( KTactileAudioToneDurationBasicLevel1, 
       
   312                          basicDuration );
       
   313         iRepository.Get( KTactileAudioToneVolumeBasicLevel1,   
       
   314                          basicParams.iVolume );
       
   315         
       
   316         // Read settings for ETouchFeedbackSensitive, level 1
       
   317         iRepository.Get( KTactileAudioToneFreqSensitiveLevel1, 
       
   318                          sensitiveParams.iFrequency );
       
   319         iRepository.Get( KTactileAudioToneDurationSensitiveLevel1,  
       
   320                          sensitiveDuration );
       
   321         iRepository.Get( KTactileAudioToneVolumeSensitiveLevel1,  
       
   322                          sensitiveParams.iVolume );
       
   323         }
       
   324     else if ( iAudioLevel == EProfileAudioFeedbackLevel2  )
       
   325         {
       
   326         // Read settings for ETouchFeedbackBasic, level 2
       
   327         iRepository.Get( KTactileAudioToneFreqBasicLevel2,     
       
   328                          basicParams.iFrequency );
       
   329         iRepository.Get( KTactileAudioToneDurationBasicLevel2, 
       
   330                          basicDuration );
       
   331         iRepository.Get( KTactileAudioToneVolumeBasicLevel2,   
       
   332                          basicParams.iVolume );
       
   333         
       
   334         // Read settings for ETouchFeedbackSensitive, level 2
       
   335         iRepository.Get( KTactileAudioToneFreqSensitiveLevel2, 
       
   336                          sensitiveParams.iFrequency );
       
   337         iRepository.Get( KTactileAudioToneDurationSensitiveLevel2,  
       
   338                          sensitiveDuration );
       
   339         iRepository.Get( KTactileAudioToneVolumeSensitiveLevel2,  
       
   340                          sensitiveParams.iVolume );        
       
   341         }
       
   342     else if ( iAudioLevel == EProfileAudioFeedbackLevel3  )
       
   343         {
       
   344         // Read settings for ETouchFeedbackBasic, level 3
       
   345         iRepository.Get( KTactileAudioToneFreqBasicLevel3,     
       
   346                          basicParams.iFrequency );
       
   347         iRepository.Get( KTactileAudioToneDurationBasicLevel3, 
       
   348                          basicDuration );
       
   349         iRepository.Get( KTactileAudioToneVolumeBasicLevel3,   
       
   350                          basicParams.iVolume );
       
   351         
       
   352         // Read settings for ETouchFeedbackSensitive, level 3
       
   353         iRepository.Get( KTactileAudioToneFreqSensitiveLevel3, 
       
   354                          sensitiveParams.iFrequency );
       
   355         iRepository.Get( KTactileAudioToneDurationSensitiveLevel3,  
       
   356                          sensitiveDuration );
       
   357         iRepository.Get( KTactileAudioToneVolumeSensitiveLevel3,  
       
   358                          sensitiveParams.iVolume );        
       
   359         }
       
   360      
       
   361     // Clear old parameters. Only do it at end, so that we still have the
       
   362     // old settings in case something fails when reading these from 
       
   363     // Central Repository.
       
   364     iSoundParams.Reset();
       
   365     
       
   366     
       
   367     // Duration is in milliseconds in central repository
       
   368     // --> Convert to microseconds
       
   369     basicParams.iDuration = 
       
   370         TTimeIntervalMicroSeconds( basicDuration * 1000 );
       
   371     sensitiveParams.iDuration = 
       
   372         TTimeIntervalMicroSeconds( sensitiveDuration * 1000 );
       
   373         
       
   374     // Volume is in precentages in central repository
       
   375     // --> Convert to 0-CMdaAudioToneUtility::MaxVolume    
       
   376     basicParams.iVolume     = ScaleVolume( basicParams.iVolume );
       
   377     sensitiveParams.iVolume = ScaleVolume( sensitiveParams.iVolume );
       
   378     
       
   379     // Store parameters for different feedback types
       
   380     iSoundParams.Append( basicParams );
       
   381     iSoundParams.Append( sensitiveParams );
       
   382     TRACE("CTactileTonePlayer::ReadSettingsL - End");        
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // Scale the volume, and perform sanity check.
       
   387 // ---------------------------------------------------------------------------
       
   388 //
       
   389 TInt CTactileTonePlayer::ScaleVolume( TInt aPercentages )
       
   390     {
       
   391     TInt maxVolume = iMdaAudioToneUtility->MaxVolume();
       
   392 
       
   393     TInt scaledVolume = ( maxVolume * aPercentages ) / 100;
       
   394     
       
   395     if ( scaledVolume > maxVolume )
       
   396         {
       
   397         scaledVolume = maxVolume;
       
   398         }
       
   399     
       
   400     return scaledVolume;    
       
   401     }
       
   402 
       
   403 // ---------------------------------------------------------------------------
       
   404 // From MCenRepNotifyHandlerCallback.
       
   405 // ---------------------------------------------------------------------------
       
   406 //    
       
   407 void CTactileTonePlayer::HandleNotifyInt( TUint32 aId, TInt aNewValue )    
       
   408     {
       
   409     TRACE("CTactileTonePlayer::HandleNotifyInt - Begin");
       
   410     if ( aId == KTactileFeedbackAudioVolume )
       
   411         {
       
   412         iAudioLevel = aNewValue;
       
   413         
       
   414         // No need to read settings if audio feedback is set off.
       
   415         if ( iAudioLevel != EProfileAudioFeedbackOff )
       
   416             {
       
   417             ReadSettings();    
       
   418             iCurrentEffectIndex = KErrNotFound;        
       
   419             }
       
   420         }
       
   421     TRACE("CTactileTonePlayer::HandleNotifyInt - End");
       
   422     }
       
   423 
       
   424 // ---------------------------------------------------------------------------
       
   425 // From MProfileChangeObserver.
       
   426 // ---------------------------------------------------------------------------
       
   427 //
       
   428 void CTactileTonePlayer::HandleActiveProfileEventL( 
       
   429     TProfileEvent /*aProfileEvent*/, 
       
   430     TInt /*aProfileId*/ )
       
   431     {
       
   432     InitializeProfilesEngineL();
       
   433     ReadSettings();    
       
   434     iCurrentEffectIndex = KErrNotFound;
       
   435     }
       
   436 
       
   437 // ---------------------------------------------------------------------------
       
   438 // Profiles engine -related initializations
       
   439 // ---------------------------------------------------------------------------
       
   440 //
       
   441 void CTactileTonePlayer::InitializeProfilesEngineL()
       
   442     {
       
   443     // Create profiles engine, if it does not yet exist
       
   444     if ( !iProfileEng )
       
   445         {
       
   446         iProfileEng = CreateProfileEngineL();        
       
   447         }
       
   448         
       
   449     MProfile* activeProfile  = iProfileEng->ActiveProfileL();
       
   450  
       
   451     const MProfileExtraSettings& extraSettings = 
       
   452      activeProfile->ProfileExtraSettings();
       
   453     
       
   454     const MProfileFeedbackSettings& feedbackSettings = 
       
   455      extraSettings.ProfileFeedbackSettings();
       
   456  
       
   457     iAudioLevel = feedbackSettings.AudioFeedback();
       
   458  
       
   459     activeProfile->Release();
       
   460     
       
   461     // Create listener for profiles changes, if it does not yet exist
       
   462     if ( !iProfileHandler ) 
       
   463         {
       
   464         iProfileHandler = CProfileChangeNotifyHandler::NewL( this );
       
   465         }
       
   466     }
       
   467 
       
   468 //---------------------------------------------------------------------------
       
   469 // ImplementationTable[]
       
   470 //
       
   471 //---------------------------------------------------------------------------
       
   472 //
       
   473 const TImplementationProxy ImplementationTable[] = 
       
   474     {
       
   475     IMPLEMENTATION_PROXY_ENTRY( 0x2001CB9D, CTactileTonePlayer::NewL )
       
   476     };
       
   477 
       
   478 //---------------------------------------------------------------------------
       
   479 // TImplementationProxy* ImplementationGroupProxy()
       
   480 //
       
   481 //---------------------------------------------------------------------------
       
   482 //
       
   483 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
   484     {
       
   485     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   486     return ImplementationTable;
       
   487     }
       
   488    
       
   489 // End of file