tactilefeedback/tactilefeedbackresolver/plugins/tactileaudioplugin/src/tactileaudioplayer.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 feedback.
       
    15 * Part of:      Tactile Feedback.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <e32debug.h>
       
    21 
       
    22 #include <centralrepository.h>
       
    23 #include <ecom/implementationproxy.h>
       
    24 
       
    25 #include <audiopreference.h>
       
    26 #include <mda/common/audio.h>
       
    27 #include <mdaaudiooutputstream.h>
       
    28 
       
    29 #include "tactilefeedbackprivatecrkeys.h"
       
    30 #include "tactilefeedbacktrace.h"
       
    31 
       
    32 #include "tactileaudioplayer.h"
       
    33 #include "OstTraceDefinitions.h"
       
    34 #ifdef OST_TRACE_COMPILER_IN_USE
       
    35 #include "tactileaudioplayerTraces.h"
       
    36 #endif
       
    37 
       
    38 const TInt KRiffHeaderSize = 44;
       
    39 _LIT8( KRiff, "RIFF" );
       
    40 _LIT8( KWave, "WAVE" );
       
    41 _LIT8( KFmt,  "fmt " );
       
    42 _LIT8( KData, "data" );
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // Constructor.
       
    46 // ---------------------------------------------------------------------------
       
    47 //
       
    48 CTactileAudioPlayer::CTactileAudioPlayer( CRepository& aRepository ):
       
    49     iRepository( aRepository )
       
    50     {
       
    51     }
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // 2nd phase constructor.
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 void CTactileAudioPlayer::ConstructL()
       
    58     {
       
    59     TRACE("CTactileAudioPlayer::ConstructL()");
       
    60     
       
    61     ReadSettingsL();
       
    62 
       
    63     CreateWavPlayerL();
       
    64 
       
    65     iCenRepNotifier = CCenRepNotifyHandler::NewL( *this, 
       
    66                                                   iRepository, 
       
    67                                                   CCenRepNotifyHandler::EIntKey,
       
    68                                                   KTactileFeedbackAudioVolume );
       
    69     iCenRepNotifier->StartListeningL(); 
       
    70 
       
    71     TRACE("CTactileAudioPlayer::ConstructL() - end");
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // 2-phased constructor.
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CTactileAudioPlayer* CTactileAudioPlayer::NewL( CRepository& aRepository )
       
    79     {
       
    80     CTactileAudioPlayer* self = 
       
    81         new ( ELeave ) CTactileAudioPlayer( aRepository );
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructL( );
       
    84     CleanupStack::Pop( self );
       
    85     return self;
       
    86     }
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 // Destructor.
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 CTactileAudioPlayer::~CTactileAudioPlayer()
       
    93     {
       
    94     if ( iAudioPlayer )
       
    95         {
       
    96         iAudioPlayer->Stop();
       
    97         delete iAudioPlayer;
       
    98         }
       
    99     
       
   100     delete iCenRepNotifier;
       
   101     delete iSensitiveSample;
       
   102     delete iBasicSample;
       
   103     delete iSensitiveFileName;
       
   104     delete iBasicFileName;
       
   105     
       
   106     iVolumeLevels.Close();
       
   107     }
       
   108 
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // From class CTactilePlayer
       
   112 //
       
   113 // Currently we only select volume level according to logical feedback type
       
   114 // (i.e. the .wav -file cannot be selected separately for each logical
       
   115 // feedback type).
       
   116 //
       
   117 // We don't do anything in case volume level has been set to zero for the
       
   118 // given feedback type (this way e.g. dragging feedback can be disabled
       
   119 // totally if that is wanted).
       
   120 //
       
   121 // Notice that currently the ETouchFeedbackSensitive -feedback is a bit
       
   122 // troublesome: Even though we have our own thread for feedback playing,
       
   123 // it still lags behind when something is dragged on screen. Final solution
       
   124 // may be to configure audio .wav dragging feedback OFF, and use audio
       
   125 // tone for dragging instead.
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 TInt CTactileAudioPlayer::PlayFeedback( TTouchLogicalFeedback aFeedback )
       
   129     {
       
   130     TRACE2( "CTactileAudioPlayer::PlayFeedback( %d )", aFeedback );
       
   131     TInt volumeIndex(0);
       
   132     
       
   133     switch ( aFeedback )
       
   134         {
       
   135         case ETouchFeedbackBasic:               // flow through
       
   136         case ETouchFeedbackBasicButton:         // flow through
       
   137         case ETouchFeedbackList:                // flow through
       
   138         case ETouchFeedbackBoundaryList:        // flow through
       
   139         case ETouchFeedbackSlider:              // flow through
       
   140         case ETouchFeedbackEdit:                // flow through
       
   141         case ETouchFeedbackSensitiveInput:
       
   142         case ETouchFeedbackLineSelection:       // flow through
       
   143         case ETouchFeedbackBlankSelection:      // flow through
       
   144         case ETouchFeedbackTextSelection:       // flow through
       
   145         case ETouchFeedbackEmptyLineSelection:  // flow through
       
   146         case ETouchFeedbackTab:                 // flow through
       
   147         case ETouchFeedbackPopUp:               // flow through
       
   148         case ETouchFeedbackIncreasingPopUp:     // flow through
       
   149         case ETouchFeedbackDecreasingPopUp:     // flow through
       
   150         case ETouchFeedbackFlick:               // flow through
       
   151         case ETouchFeedbackCheckbox:            // flow through
       
   152         case ETouchFeedbackCharacterInputButton:
       
   153         case ETouchFeedbackMultiTouchRecognized:
       
   154             volumeIndex = 0;
       
   155             break;
       
   156         case ETouchFeedbackSensitive:           // flow through
       
   157         case ETouchFeedbackSensitiveButton:     // flow through
       
   158         case ETouchFeedbackSensitiveList:      
       
   159             volumeIndex = 1;
       
   160             break;
       
   161         default:
       
   162             // should not be there at all
       
   163             TRACE2( "CTactileAudioPlayer::PlayFeedback - %d is not a feedback type - returning", aFeedback );
       
   164             break;
       
   165         }
       
   166     
       
   167     
       
   168     if ( volumeIndex <= iVolumeLevels.Count() &&
       
   169          iVolumeLevels[volumeIndex] > 0 &&
       
   170          iAudioPlayer )
       
   171         {
       
   172         switch ( iState )
       
   173             {
       
   174             case ETactileAudioInitialising:
       
   175                 // can't play anything yet
       
   176                 break;
       
   177             case ETactileAudioPlaying: // fall trough
       
   178             case ETactileAudioReady:
       
   179                 OstTrace1( TACTILE_PERFORMANCE, TACTILE_PLAY_AUDIO_FEEDBACK_1,
       
   180                                 "e_TACTILE_PLAY_AUDIO_FEEDBACK 1 0x%x", aFeedback );
       
   181 
       
   182                 if ( aFeedback == ETouchFeedbackBasic )
       
   183                     {
       
   184                     TRAP_IGNORE( iAudioPlayer->WriteL( *iBasicSample ) );
       
   185                     }
       
   186                 else
       
   187                     {
       
   188                     TRAP_IGNORE( iAudioPlayer->WriteL( *iSensitiveSample ) );
       
   189                     }                    
       
   190                 OstTrace1( TACTILE_PERFORMANCE, TACTILE_PLAY_AUDIO_FEEDBACK_0,
       
   191                                 "e_TACTILE_PLAY_AUDIO_FEEDBACK 0 0x%x", aFeedback );
       
   192                 iState = ETactileAudioPlaying;
       
   193                 break;
       
   194             case ETactileAudioError: 
       
   195                 break;
       
   196             default:
       
   197                 // should not be here
       
   198                 TRACE("CTactileAudioPlayer::PlayFeedback - error with audio device");
       
   199                 break;
       
   200                     
       
   201             }
       
   202 
       
   203         }
       
   204     else 
       
   205         {
       
   206         if ( !iAudioPlayer )
       
   207             {
       
   208             TRACE("CTactileAudioPlayer::PlayFeedback - iAudioPlayer is NULL!");
       
   209             }
       
   210         else
       
   211             {
       
   212             TRACE("CTactileAudioPlayer::PlayFeedback - volume levels not ok");
       
   213             }
       
   214         }
       
   215     TRACE2( "CTactileAudioPlayer::PlayFeedback( %d ) - end", aFeedback );
       
   216     return KErrNone;
       
   217     }
       
   218     
       
   219 // ---------------------------------------------------------------------------
       
   220 //
       
   221 // ---------------------------------------------------------------------------
       
   222 //    
       
   223 TInt CTactileAudioPlayer::PlayPreviewFeedback( TInt aLevel, 
       
   224                                              TTouchLogicalFeedback aFeedback )    
       
   225     {
       
   226     TRACE("CTactileAudioPlayer::PlayPreviewFeedback - Begin");
       
   227     TInt ret( KErrArgument );
       
   228     
       
   229     iOriginalVolume = iCurrentVolume;
       
   230     iCurrentVolume = aLevel;
       
   231     iAudioPlayer->SetVolume( ScaledVolume() );
       
   232     ret = PlayFeedback( aFeedback );
       
   233     iCurrentVolume = iOriginalVolume;
       
   234     iAudioPlayer->SetVolume( ScaledVolume() );
       
   235     
       
   236     TRACE("CTactileAudioPlayer::PlayPreviewFeedback - End");
       
   237     return ret;    
       
   238     }    
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // 
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void CTactileAudioPlayer::MaoscOpenComplete( TInt aError )
       
   245     {
       
   246     if ( aError == KErrNone ) 
       
   247         {
       
   248         iCurrentVolume = iVolumeLevels[0];
       
   249         iMaxRawVolume = iAudioPlayer->MaxVolume();
       
   250         iRepository.Get( KTactileFeedbackAudioVolume, iCurrentVolume );
       
   251         iAudioPlayer->SetVolume( ScaledVolume() );
       
   252         TRAP_IGNORE( iAudioPlayer->SetDataTypeL( KMMFFourCCCodePCM16 ) );
       
   253         iState = ETactileAudioReady;        
       
   254         }
       
   255     else 
       
   256         {
       
   257         TRACE2("CTactileAudioPlayer::MaoscOpenComplete( %d ) failed, will not play feedback", aError );
       
   258         delete iAudioPlayer;
       
   259         iAudioPlayer = NULL;
       
   260         
       
   261         iState = ETactileAudioError;
       
   262         }
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // 
       
   267 // ---------------------------------------------------------------------------
       
   268 //
       
   269 void CTactileAudioPlayer::MaoscPlayComplete( TInt aError )
       
   270     {
       
   271     TRACE("CTactileAudioPlayer::MaoscPlayComplete - Begin");
       
   272     iAudioPlayer->Stop();
       
   273     if ( aError == KErrCorrupt )
       
   274         {
       
   275         TRACE2("CTactileAudioPlayer::MaoscPlayComplete( %d ) failed, will not play feedback", aError );
       
   276         delete iAudioPlayer;
       
   277         iAudioPlayer = NULL;
       
   278         
       
   279         iState = ETactileAudioError;        
       
   280         }
       
   281     else
       
   282         {   
       
   283         iState = ETactileAudioReady;
       
   284         }            
       
   285     TRACE("CTactileAudioPlayer::MaoscPlayComplete - End");
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------
       
   289 // 
       
   290 // ---------------------------------------------------------------------------
       
   291 //    
       
   292 void CTactileAudioPlayer::MaoscBufferCopied( TInt aError, const TDesC8& /*aBuffer*/ )
       
   293     {
       
   294     if ( !aError )
       
   295         {
       
   296         iState = ETactileAudioReady; // may write another sample
       
   297         }
       
   298     else
       
   299         {
       
   300         TRACE2("CTactileAudioPlayer::MaoscPlayComplete( %d ) failed", aError);
       
   301         }
       
   302     }
       
   303 
       
   304 // ---------------------------------------------------------------------------
       
   305 // Settings are now not read completely, as only the .wav -file of basic
       
   306 // feedback is read, and same file is used for sensitive feedback. 
       
   307 // Using of separate files for basic and sensitive feedback 
       
   308 // can be added later in case necessary.
       
   309 // ---------------------------------------------------------------------------
       
   310 //
       
   311 void CTactileAudioPlayer::ReadSettingsL()
       
   312     {
       
   313     TRACE("CTactileAudioPlayer::ReadSettingsL - Begin");
       
   314     
       
   315     iVolumeLevels.Reset();
       
   316     
       
   317     delete iSensitiveFileName;
       
   318     iSensitiveFileName = NULL;
       
   319 
       
   320     delete iBasicFileName;
       
   321     iBasicFileName = NULL;
       
   322 
       
   323     iSensitiveFileName = HBufC::NewL( KMaxFileName );    
       
   324     TPtr sensitiveFileName = iSensitiveFileName->Des();
       
   325 
       
   326     iBasicFileName = HBufC::NewL( KMaxFileName );    
       
   327     TPtr basicFileName = iBasicFileName->Des();
       
   328 
       
   329     TInt basicVolumeLevel = 0;
       
   330     TInt sensitiveVolumeLevel = 0;
       
   331     
       
   332     // Read volume values for level 2
       
   333     iRepository.Get( KTactileAudioWavVolumeBasicLevel2, basicVolumeLevel );
       
   334 
       
   335     
       
   336     iRepository.Get( KTactileAudioWavVolumeSensitiveLevel2, sensitiveVolumeLevel );
       
   337 
       
   338     // Read file names
       
   339     iRepository.Get( KTactileAudioWavFileBasicLevel2, basicFileName );
       
   340 
       
   341     iRepository.Get( KTactileAudioWavFileSensitiveLevel2, sensitiveFileName );
       
   342     
       
   343     iVolumeLevels.Append( basicVolumeLevel );
       
   344     iVolumeLevels.Append( sensitiveVolumeLevel );
       
   345     
       
   346     TRACE("CTactileAudioPlayer::ReadSettingsL() - End");
       
   347     }
       
   348 
       
   349 
       
   350 // ---------------------------------------------------------------------------
       
   351 // ScaledVolume()
       
   352 // return 100% scaled & sanity checked volume value
       
   353 // ---------------------------------------------------------------------------
       
   354 //
       
   355 TInt CTactileAudioPlayer::ScaledVolume()
       
   356     {
       
   357     if ( iMaxRawVolume == KErrNotFound )
       
   358         {
       
   359         TRACE( "CTactileAudioPlayer::ScaledVolume() Audio Hardware is not initialized properly" );
       
   360         return 0;
       
   361         }
       
   362     
       
   363     TInt volume = iMaxRawVolume * iCurrentVolume / 100;
       
   364 
       
   365     if ( volume > iMaxRawVolume )
       
   366         {
       
   367         // sanity check, we might get anything from cenrep
       
   368         volume = iMaxRawVolume;
       
   369         }
       
   370 
       
   371     TRACE4( "CTactileAudioPlayer::ScaledVolume() iCurrentVolume:%d scales volume to:%d out of iMaxRawVolume:%d",
       
   372         iCurrentVolume, volume, iMaxRawVolume );
       
   373         
       
   374     return volume;
       
   375     }
       
   376 
       
   377 /*
       
   378 * Wave file structure: Riff header + Wave format chunk + Wave data chunk
       
   379 * 
       
   380 * Riff header:
       
   381 * ==================================================
       
   382 * Offset Size Description      Value
       
   383 * 0x00      4 Chunk ID         "RIFF"
       
   384 * 0x04      4 Chunk Data Size  ( file size ) - 8
       
   385 * 0x08      4 RIFF Type        "WAVE"
       
   386 * 0x0c      *  Wave chunks *
       
   387 *
       
   388 * Wave Format Chunk:
       
   389 * ==================================================
       
   390 * Offset Size Description      Value
       
   391 * 0x00      4 Chunk ID         "fmt "
       
   392 * 0x04      4 Chunk Data Size  16 + extra format bytes ( 0 for normal wav files)
       
   393 * 0x08      2 Compression code 1...65535               ( 1 for PCM uncompressed)
       
   394 * 0x0a      2 Nbr of channels  1...65535
       
   395 * 0x0c      4 Sample rate      1...0xFFFFFFFF
       
   396 * 0x10      4 Average bytes per sec
       
   397 * 0x14      2 block align
       
   398 * 0x16      2 siginificant bits per sample
       
   399 * 0x18      2 extra format bytes 0...65535
       
   400 * 0x1a        * extra format bytes, if any *
       
   401 *
       
   402 * Wave Data Chunk:
       
   403 * ==================================================
       
   404 * Offset Size Description      Value
       
   405 * 0x00      4 Chunk ID         "data"
       
   406 * 0x04      4 Chunk data size  
       
   407 * 0x08        * sample data *
       
   408 *
       
   409 */
       
   410 void CTactileAudioPlayer::ReadSampleL( RFile& aFile, 
       
   411                                        HBufC8*& aDes, 
       
   412                                        TUint& aChannels, 
       
   413                                        TUint& aSampleRate )
       
   414     {
       
   415     TRACE("CTactileAudioPlayer::ReadSampleL - Start");
       
   416     const TInt fmtOffset  = 0x0c;
       
   417     const TInt dataOffset = fmtOffset + 0x18;
       
   418     
       
   419     TBuf8<KRiffHeaderSize> header;
       
   420     TInt err = aFile.Read( header, KRiffHeaderSize );
       
   421     if ( err )
       
   422         {
       
   423         TRACE("CTactileAudioPlayer::ReadSampleL: reading from file failed, aborting");
       
   424         User::Leave( err );
       
   425         }
       
   426 
       
   427     TPtr8 p = header.LeftTPtr( 4 );
       
   428     
       
   429     if ( p.Compare( KRiff ) )
       
   430         {
       
   431         TRACE("CTactileAudioPlayer::ReadSampleL: no RIFF header found, aborting" );
       
   432         User::Leave( KErrCorrupt );
       
   433         }
       
   434 
       
   435     p = header.MidTPtr( 0x08, 4 );
       
   436     if ( p.Compare( KWave ) )
       
   437         {
       
   438         TRACE("CTactileAudioPlayer::ReadSampleL:  not a WAVE file, aborting" );
       
   439         User::Leave( KErrCorrupt );
       
   440         }
       
   441 
       
   442     p = header.MidTPtr( fmtOffset + 0x00, 4 );
       
   443     if ( p.Compare( KFmt ) )
       
   444         {
       
   445         TRACE("CTactileAudioPlayer::ReadSampleL:  no 'fmt ' chunk found, aborting" );
       
   446         User::Leave( KErrCorrupt );
       
   447         }
       
   448 
       
   449     p = header.MidTPtr( dataOffset, 4 );
       
   450     if ( p.Compare( KData ) )
       
   451         {
       
   452         TRACE("CTactileAudioPlayer::ReadSampleL:  no 'data' chunk found, aborting" );
       
   453         User::Leave( KErrCorrupt );
       
   454         }
       
   455 
       
   456     TUint8 lo = header[ fmtOffset + 0x08 ];
       
   457     TUint8 hi = header[ fmtOffset + 0x08 + 1 ];
       
   458     if ( !( lo == 1 && hi == 0) )
       
   459         {
       
   460         TRACE("CTactileAudioPlayer::ReadSampleL: non PCM wav not supported, aborting" );
       
   461         User::Leave( KErrNotSupported );
       
   462         }
       
   463 
       
   464     lo = header[ fmtOffset + 0x0a ];
       
   465     hi = header[ fmtOffset + 0x0a + 1 ];
       
   466     aChannels = lo;
       
   467     if ( !(aChannels == 1 || aChannels == 2 && hi == 0) )
       
   468         {
       
   469         TRACE2("CTactileAudioPlayer::ReadSampleL: unsupported number of channels ( %d ), aborting", aChannels );
       
   470         User::Leave( KErrNotSupported );
       
   471         }
       
   472 
       
   473     aSampleRate = 0;
       
   474     for ( TInt i = 0; i < 4; i++ )
       
   475         {
       
   476         lo = header[ fmtOffset + 0x0c + i ];
       
   477         TUint32 tmp = lo;
       
   478         tmp = tmp << i * 8;
       
   479 
       
   480         aSampleRate = aSampleRate | tmp;
       
   481         }
       
   482 
       
   483     lo = header[ fmtOffset + 0x16 ];
       
   484     hi = header[ fmtOffset + 0x16 + 1 ];
       
   485     TUint16 bitsPerSample = hi;
       
   486     bitsPerSample = bitsPerSample << 8;
       
   487     bitsPerSample = bitsPerSample | lo;
       
   488 
       
   489     if ( bitsPerSample != 16 )
       
   490         {
       
   491         TRACE2("CTactileAudioPlayer::ReadSampleL:  %d bits per sample not supported", bitsPerSample );
       
   492         User::Leave( KErrNotSupported );
       
   493         }
       
   494 
       
   495     TUint32 bytesPerSample = bitsPerSample / 8;
       
   496     
       
   497     // how many bytes for 6 ms
       
   498     TUint bytesNeeded = ( aSampleRate * aChannels * bytesPerSample * 6 ) / 1000;
       
   499 
       
   500     TInt fsize( 0 );
       
   501     if ( aFile.Size( fsize ) == KErrNone && fsize >= bytesNeeded + KRiffHeaderSize )
       
   502         {
       
   503         aDes = HBufC8::NewL( bytesNeeded );
       
   504         TPtr8 des = aDes->Des();
       
   505         aFile.Read( des, bytesNeeded );
       
   506         }
       
   507     else
       
   508         {
       
   509         TRACE("CTactileAudioPlayer::ReadSampleL: Less than 6ms content in file, aborting" );
       
   510         User::Leave( KErrNotSupported );
       
   511         }
       
   512 
       
   513     TRACE3("CTactileAudioPlayer::ReadSampleL %dHz %dchannel sample read successfully - End", 
       
   514         iSampleRate, iChannels);
       
   515     }
       
   516 
       
   517 // ---------------------------------------------------------------------------
       
   518 // Audio data reading from file and creation of the actual player utility.
       
   519 //
       
   520 // Rest of the initializations are done in MapcInitComplete -function.
       
   521 //
       
   522 // Notice that CMdaAudioOutputStream usage is not a good idea, as it
       
   523 // buffers samples until buffer is full and flushes all in a row. Result is 
       
   524 // no feedback first, then a machine gun burst at some completely 
       
   525 // unrelated moment. 
       
   526 // ---------------------------------------------------------------------------
       
   527 //
       
   528 void CTactileAudioPlayer::CreateWavPlayerL()
       
   529     {
       
   530     TRACE("CTactileAudioPlayer::CreateWavPlayerL - Start");
       
   531     iState = ETactileAudioInitialising;
       
   532     delete iBasicSample;
       
   533     iBasicSample = NULL;
       
   534     delete iSensitiveSample;
       
   535     iSensitiveSample = NULL;
       
   536 
       
   537     if ( !( iBasicFileName && iBasicFileName->Length() > 0  && 
       
   538             iSensitiveFileName && iSensitiveFileName->Length() > 0 ))
       
   539         {
       
   540         TRACE("CTactileAudioPlayer::CreateWavPlayerL filenames missing, aborting");
       
   541         User::Leave( KErrBadName );
       
   542         }
       
   543 
       
   544     RFs fs;
       
   545     User::LeaveIfError ( fs.Connect() ); 
       
   546     CleanupClosePushL( fs );
       
   547         
       
   548     RFile file;
       
   549     TInt err = file.Open( fs, *iBasicFileName, EFileRead );
       
   550     if ( err )
       
   551         {
       
   552         TRACE2("CTactileAudioPlayer::CreateWavPlayerL could not open %S, aborting", iBasicFileName );
       
   553         User::Leave( err );
       
   554         }
       
   555 
       
   556     CleanupClosePushL( file );
       
   557     ReadSampleL( file, iBasicSample, iChannels, iSampleRate );
       
   558     CleanupStack::PopAndDestroy(&file); 
       
   559     
       
   560     RFile file2; 
       
   561     err = file2.Open( fs, *iSensitiveFileName, EFileRead );
       
   562     if ( err )
       
   563         {
       
   564         TRACE2("CTactileAudioPlayer::CreateWavPlayerL could not open %S, aborting", iSensitiveFileName );
       
   565         User::Leave( err );
       
   566         }
       
   567 
       
   568     CleanupClosePushL( file2 );
       
   569     
       
   570     TUint sampleRate(0);
       
   571     TUint channels(0);
       
   572     ReadSampleL( file2, iSensitiveSample, channels, sampleRate );
       
   573     CleanupStack::PopAndDestroy( &file2 );  
       
   574     CleanupStack::PopAndDestroy( &fs );
       
   575     
       
   576     if ( channels != iChannels || sampleRate != iSampleRate )
       
   577         {
       
   578         TRACE("CTactileAudioPlayer::CreateWavPlayerL Sample rates and number of channels must be same for both files, aborting");
       
   579         User::Leave( KErrNotSupported );
       
   580         }
       
   581     
       
   582     TInt priority = KAudioPriorityKeyPressNonDTMFWithFeedback; 
       
   583     TMdaPriorityPreference pref = static_cast<TMdaPriorityPreference>(KAudioPrefKeyPressNonDTMFWithFeedback);
       
   584     
       
   585     iAudioPlayer = CMdaAudioOutputStream::NewL( *this ,priority, pref); 
       
   586         
       
   587     TMdaAudioDataSettings streamSettings;
       
   588     switch ( iChannels )
       
   589         {
       
   590         case 1:
       
   591             streamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
       
   592             break;
       
   593         case 2:
       
   594             streamSettings.iChannels = TMdaAudioDataSettings::EChannelsStereo;
       
   595             TRACE("CTactileAudioPlayer::CreateWavPlayerL Warning: stereo wav for feedback");
       
   596             break;
       
   597         default:
       
   598             TRACE2("CTactileAudioPlayer::CreateWavPlayerL: unsupported number of channels %d, aborting", iChannels );
       
   599             User::Leave( KErrNotSupported );
       
   600             break;
       
   601         }
       
   602     
       
   603     // there must be easier way to do this...
       
   604     switch( iSampleRate )
       
   605         {
       
   606         case 48000:
       
   607             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate48000Hz;
       
   608             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate48000Hz;
       
   609             break;
       
   610         case 44100:
       
   611             TRACE2("CTactileAudioPlayer::CreateWavPlayerL: warning, samplerate %d causes performance problem", iSampleRate );
       
   612             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate44100Hz;
       
   613             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate44100Hz;
       
   614             break;
       
   615         case 32000:
       
   616             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate32000Hz;
       
   617             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate32000Hz;
       
   618             break;
       
   619         case 24000:
       
   620             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate24000Hz;
       
   621             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate24000Hz;
       
   622             break;
       
   623         case 16000:
       
   624             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz;
       
   625             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate16000Hz;
       
   626             break;
       
   627         case 12000:
       
   628             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate12000Hz;
       
   629             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate12000Hz;
       
   630             break;
       
   631         case 11025:
       
   632             TRACE2("CTactileAudioPlayer::CreateWavPlayerL: warning, samplerate %d causes performance problem",iSampleRate );
       
   633             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz;
       
   634             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate11025Hz;
       
   635             break;
       
   636         case 8000:
       
   637             streamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
       
   638             streamSettings.iCaps = TMdaAudioDataSettings::ESampleRate8000Hz;
       
   639             break;
       
   640         default:
       
   641             TRACE2("CTactileAudioPlayer::CreateWavPlayerL: unsupported samplerate %d, aborting",iSampleRate );
       
   642             User::Leave( KErrNotSupported );
       
   643             break;
       
   644         }
       
   645     
       
   646     iAudioPlayer->Open( &streamSettings );
       
   647 
       
   648     TRACE("CTactileAudioPlayer::CreateWavPlayerL - End");
       
   649     }
       
   650 
       
   651 // ---------------------------------------------------------------------------
       
   652 // 
       
   653 // ---------------------------------------------------------------------------
       
   654 //    
       
   655 void CTactileAudioPlayer::HandleNotifyInt( TUint32 aId, TInt aNewValue )    
       
   656     {
       
   657     TRACE("CTactileTonePlayer::HandleNotifyInt - Begin");
       
   658     if ( aId == KTactileFeedbackAudioVolume )
       
   659         {
       
   660         iCurrentVolume = aNewValue;
       
   661         iAudioPlayer->SetVolume( ScaledVolume() );
       
   662         }
       
   663     TRACE("CTactileTonePlayer::HandleNotifyInt - End");
       
   664     }
       
   665 
       
   666 
       
   667 //---------------------------------------------------------------------------
       
   668 // ImplementationTable[]
       
   669 //
       
   670 //---------------------------------------------------------------------------
       
   671 //
       
   672 const TImplementationProxy ImplementationTable[] = 
       
   673     {
       
   674     IMPLEMENTATION_PROXY_ENTRY( 0x2002133A, CTactileAudioPlayer::NewL )
       
   675     };
       
   676 
       
   677 //---------------------------------------------------------------------------
       
   678 // TImplementationProxy* ImplementationGroupProxy()
       
   679 //
       
   680 //---------------------------------------------------------------------------
       
   681 //
       
   682 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
   683     {
       
   684     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   685     return ImplementationTable;
       
   686     }
       
   687    
       
   688 
       
   689    
       
   690 // End of file