srsf/speechsynthesis/server/src/speechsynthesisserver.cpp
branchRCL_3
changeset 23 e36f3802f733
equal deleted inserted replaced
22:cad71a31b7fc 23:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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:  Speech synthesis server
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 
       
    21 #include <AudioOutput.h>
       
    22 #include <nssttscommon.h>
       
    23 
       
    24 #include "speechsynthesisserver.h"
       
    25 
       
    26 #include "speechsynthesisclientserver.h"
       
    27 #include "speechsynthesisserverutilities.h"
       
    28 #include "speechsynthesissession.h"
       
    29 
       
    30 #include "rubydebug.h"
       
    31 
       
    32 
       
    33 // CONSTANTS
       
    34 
       
    35 // Time to wait before tts plugin is closed if no activity detected. 
       
    36 const TTimeIntervalMicroSeconds32 KTtsPluginCloseWait = 30000000; // 30 sec.
       
    37 
       
    38 // ----------------------------------------------------------------------------
       
    39 // RunServerL
       
    40 // Server startup code
       
    41 // Perform all server initialisation, in particular creation of the
       
    42 // scheduler and server and then run the scheduler
       
    43 // ----------------------------------------------------------------------------
       
    44 //  
       
    45 static void RunServerL()
       
    46     {
       
    47     RUBY_DEBUG_BLOCK( "SpeechSynthesisServer: RunServerL" );
       
    48     
       
    49     // Naming the server thread after the server helps to debug panics
       
    50     User::LeaveIfError( User::RenameThread( KSpeechSynthesisServerName ) );
       
    51 
       
    52     // Create and install the active scheduler we need
       
    53     CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
       
    54     CleanupStack::PushL( scheduler );
       
    55     CActiveScheduler::Install( scheduler );
       
    56     
       
    57     // Create the server (leave it on the cleanup stack)
       
    58     CServer2* server = CSpeechSynthesisServer::NewLC();
       
    59     
       
    60     // Initialisation complete, now signal the client
       
    61     RProcess::Rendezvous( KErrNone );
       
    62 
       
    63     RUBY_DEBUG0( "SpeechSynthesisServer: server fully running." );
       
    64     
       
    65     // Ready to run
       
    66     CActiveScheduler::Start();
       
    67     
       
    68     RUBY_DEBUG0( "SpeechSynthesisServer: server closing." );
       
    69     
       
    70     // Cleanup the server and scheduler
       
    71     CleanupStack::PopAndDestroy( server );
       
    72     CleanupStack::PopAndDestroy( scheduler );
       
    73     }
       
    74 
       
    75 // ----------------------------------------------------------------------------
       
    76 // E32Main
       
    77 // Server process entry-point
       
    78 // ----------------------------------------------------------------------------
       
    79 //
       
    80 TInt E32Main()
       
    81     {
       
    82     __UHEAP_MARK;
       
    83     
       
    84     RUBY_DEBUG0( "SpeechSynthesisServer: E32Main" );
       
    85     
       
    86     CTrapCleanup* cleanup = CTrapCleanup::New();
       
    87     
       
    88     TInt error( KErrNoMemory );
       
    89     
       
    90     if ( cleanup )
       
    91         {
       
    92         TRAP( error, RunServerL() );
       
    93         delete cleanup;
       
    94         }
       
    95         
       
    96     __UHEAP_MARKEND;
       
    97     
       
    98     return error;
       
    99     }
       
   100     
       
   101     
       
   102 // ----------------------------------------------------------------------------
       
   103 // LanguageOrder
       
   104 // Used in CSpeechSynthesisServer::GetSupportedLanguagesL()
       
   105 // ----------------------------------------------------------------------------
       
   106 // 
       
   107 static TInt LanguageOrder( const TLanguage& a, const TLanguage& b )
       
   108     {
       
   109     TInt result( 0 );
       
   110     
       
   111     if ( a < b )
       
   112         {
       
   113         result = -1;
       
   114         }
       
   115     else if ( a > b )
       
   116         {
       
   117         result = 1;
       
   118         }
       
   119 
       
   120     return result;
       
   121     }
       
   122 
       
   123 
       
   124 // ----------------------------------------------------------------------------
       
   125 // CSpeechSynthesisServer::CSpeechSynthesisServer
       
   126 // Constructor
       
   127 // ----------------------------------------------------------------------------
       
   128 inline CSpeechSynthesisServer::CSpeechSynthesisServer() :
       
   129     CPolicyServer( CActive::EPriorityStandard, 
       
   130                    KSpeechSynthesisPolicy, 
       
   131                    ESharableSessions ),
       
   132     iOpenTtsPlugin( KNullUid ),
       
   133     iSessionPriority( EMdaPriorityMin ), 
       
   134     iDefaultSpeakingRate( KTtsMaxSpeakingRate / 2 ),
       
   135     iDefaultAudioPriority( EMdaPriorityNormal ),
       
   136     iDefaultAudioPreference( EMdaPriorityPreferenceTimeAndQuality )
       
   137     {
       
   138     // Nothing
       
   139     }
       
   140     
       
   141 // ----------------------------------------------------------------------------
       
   142 // CSpeechSynthesisServer::~CSpeechSynthesisServer
       
   143 // Destructor
       
   144 // ----------------------------------------------------------------------------
       
   145 //
       
   146 CSpeechSynthesisServer::~CSpeechSynthesisServer()
       
   147     {    
       
   148     delete iTtsUtility;
       
   149     delete iShutdown;
       
   150     delete iConfigurationListener;
       
   151     delete iMMCListener; 
       
   152     
       
   153     iTtsVoiceConfigs.Close();
       
   154     
       
   155     if ( iPluginCloser )
       
   156         {
       
   157         iPluginCloser->Cancel();
       
   158         delete iPluginCloser;
       
   159         }
       
   160     }
       
   161 
       
   162 // ----------------------------------------------------------------------------
       
   163 // CSpeechSynthesisServer::NewLC
       
   164 // 
       
   165 // ----------------------------------------------------------------------------
       
   166 //
       
   167 CServer2* CSpeechSynthesisServer::NewLC()
       
   168     {
       
   169     RUBY_DEBUG0( "CSpeechSynthesisServer::NewLC" );
       
   170     
       
   171     CSpeechSynthesisServer* self = new(ELeave) CSpeechSynthesisServer();
       
   172     
       
   173     CleanupStack::PushL( self );
       
   174     self->ConstructL();
       
   175     
       
   176     return self;
       
   177     }
       
   178 
       
   179 // ----------------------------------------------------------------------------
       
   180 // CSpeechSynthesisServer::ConstructL
       
   181 // 2nd phase construction - ensure the timer and server objects are running
       
   182 // ----------------------------------------------------------------------------
       
   183 //
       
   184 void CSpeechSynthesisServer::ConstructL()
       
   185     {
       
   186     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ConstructL" );
       
   187     
       
   188     StartL( KSpeechSynthesisServerName );
       
   189     
       
   190     iTtsUtility = CTtsUtility::NewL( *this );
       
   191     iTtsUtility->SetPriority( iDefaultAudioPriority, 
       
   192                               (TMdaPriorityPreference)iDefaultAudioPreference );
       
   193     
       
   194     // Create object for closing tts plugin when server has been idle for a while. 
       
   195     iPluginCloser = CPeriodic::NewL( CActive::EPriorityIdle );
       
   196      
       
   197     // Listens for changes in SIS installations
       
   198     iConfigurationListener = CConfigurationListener::NewL( *this );
       
   199     
       
   200     // Listens insertions and removals of MMC. 
       
   201     iMMCListener = CMMCListener::NewL( *this );
       
   202     
       
   203     UpdateSynthesisConfigurationL();
       
   204     
       
   205     // Ensure that the server still exits even if the 1st client fails to connect
       
   206     iShutdown = CShutdown::NewL();
       
   207     iShutdown->Cancel();
       
   208     iShutdown->Start();
       
   209     }
       
   210 
       
   211 // ----------------------------------------------------------------------------
       
   212 // CSpeechSynthesisServer::AddSession
       
   213 // A new session is being created
       
   214 // Cancel the shutdown timer if it was running
       
   215 // ----------------------------------------------------------------------------
       
   216 //
       
   217 void CSpeechSynthesisServer::AddSession()
       
   218     {
       
   219     RUBY_DEBUG0( "CSpeechSynthesisServer::AddSession" );
       
   220     
       
   221     iSessionCount++;
       
   222     
       
   223     iShutdown->Cancel();
       
   224     }
       
   225 
       
   226 // ----------------------------------------------------------------------------
       
   227 // CSpeechSynthesisServer::DropSession
       
   228 // A session is being destroyed
       
   229 // Start the shutdown timer if it is the last session.
       
   230 // ----------------------------------------------------------------------------
       
   231 //
       
   232 void CSpeechSynthesisServer::DropSession()
       
   233     {
       
   234     RUBY_DEBUG0( "CSpeechSynthesisServer::DropSession" );
       
   235     
       
   236     iSessionCount--;
       
   237     
       
   238     if ( iSessionCount == 0 )
       
   239         {
       
   240         iShutdown->Cancel();
       
   241         iShutdown->Start();
       
   242         }
       
   243     }
       
   244     
       
   245 // ----------------------------------------------------------------------------
       
   246 // CSpeechSynthesisServer::ReserveL
       
   247 //
       
   248 // ----------------------------------------------------------------------------
       
   249 //
       
   250 void CSpeechSynthesisServer::ReserveL( MSpeechSynthesisServerObserver* aSession )
       
   251     {
       
   252     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ReserveL" );
       
   253     
       
   254     iPluginCloser->Cancel();
       
   255     
       
   256     if ( !iSession || iSession == aSession )
       
   257         {
       
   258         // Session is not in use or it's reserved already for this session
       
   259         iSession = aSession;
       
   260         }
       
   261     else
       
   262         {
       
   263         User::Leave( KErrInUse );
       
   264         }
       
   265     }
       
   266 
       
   267 // ----------------------------------------------------------------------------
       
   268 // CSpeechSynthesisServer::ReserveL
       
   269 //
       
   270 // ----------------------------------------------------------------------------
       
   271 //
       
   272 void CSpeechSynthesisServer::ReserveL( MSpeechSynthesisServerObserver* aSession,
       
   273                                        TInt aPriority )
       
   274     {
       
   275     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ReserveL" );
       
   276     
       
   277     iPluginCloser->Cancel();
       
   278     
       
   279     if ( !iSession || iSession == aSession )
       
   280         {
       
   281         // Session is not in use or it's reserved already for this session
       
   282         iSession = aSession;
       
   283         
       
   284         iSessionPriority = aPriority;
       
   285         }
       
   286     else if ( aPriority > iSessionPriority )
       
   287         {
       
   288         Stop();
       
   289         
       
   290         iSession->MsssOperationAborted();
       
   291         
       
   292         iPreviousSession = iSession;
       
   293         iSession = aSession; 
       
   294         iSessionPriority = aPriority; 
       
   295         }
       
   296     else 
       
   297         {
       
   298         User::Leave( KErrInUse ); 
       
   299         }
       
   300     }
       
   301     
       
   302 // ----------------------------------------------------------------------------
       
   303 // CSpeechSynthesisServer::Release
       
   304 //
       
   305 // ----------------------------------------------------------------------------
       
   306 //
       
   307 void CSpeechSynthesisServer::Release( const MSpeechSynthesisServerObserver* aSession )
       
   308     {
       
   309     RUBY_DEBUG0( "CSpeechSynthesisServer::Release" );
       
   310     
       
   311     if ( iSession == aSession )
       
   312         {
       
   313         iPreviousSession = iSession;
       
   314         iSession = NULL; 
       
   315         iSessionPriority = EMdaPriorityMin;
       
   316         
       
   317         TRAP_IGNORE( UpdateSynthesisConfigurationIfNeededL() );
       
   318         
       
   319         iPluginCloser->Cancel();
       
   320         iPluginCloser->Start( KTtsPluginCloseWait, KTtsPluginCloseWait,
       
   321                               TCallBack( ClosePlugin, this ) );
       
   322         
       
   323         RUBY_DEBUG0( "iPluginCloser started" );
       
   324         }
       
   325     }
       
   326 
       
   327 // ----------------------------------------------------------------------------
       
   328 // CSpeechSynthesisServer::GetDefaultSettingsL
       
   329 //
       
   330 // ----------------------------------------------------------------------------
       
   331 //
       
   332 void CSpeechSynthesisServer::GetDefaultSettingsL( TVoice& aVoice, 
       
   333                                   TInt& aSpeakingRate, TInt& aMaxSpeakingRate,
       
   334                                   TInt& aVolume, TInt& aMaxVolume, 
       
   335                                   TInt& aAudioPriority, TInt& aAudioPreference,
       
   336                                   TInt& aAudioOutput )
       
   337     {
       
   338     UpdateSynthesisConfigurationIfNeededL();
       
   339     
       
   340     aVoice           = iDefaultVoice;
       
   341     aSpeakingRate    = iDefaultSpeakingRate;
       
   342     aMaxSpeakingRate = KTtsMaxSpeakingRate;
       
   343     aVolume          = iDefaultVolume;
       
   344     aMaxVolume       = iDefaultMaxVolume;
       
   345     aAudioPriority   = iDefaultAudioPriority;
       
   346     aAudioPreference = iDefaultAudioPreference;
       
   347     aAudioOutput     = RSpeechSynthesis::ETtsOutputDefault;
       
   348     }
       
   349 
       
   350 // ----------------------------------------------------------------------------
       
   351 // CSpeechSynthesisServer::GetDefaultVoiceL
       
   352 //
       
   353 // ----------------------------------------------------------------------------
       
   354 //
       
   355 void CSpeechSynthesisServer::GetDefaultVoiceL( TVoice& aVoice )
       
   356     {
       
   357     UpdateSynthesisConfigurationIfNeededL();
       
   358     
       
   359     aVoice = iDefaultVoice;
       
   360     }
       
   361 
       
   362 // ----------------------------------------------------------------------------
       
   363 // CSpeechSynthesisServer::PrimeL
       
   364 //
       
   365 // ----------------------------------------------------------------------------
       
   366 //
       
   367 void CSpeechSynthesisServer::PrimeL( const TDesC& aText )
       
   368     {
       
   369     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::PrimeL" );
       
   370     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   371     
       
   372     iTtsUtility->OpenDesL( aText );
       
   373     }
       
   374     
       
   375 // ----------------------------------------------------------------------------
       
   376 // CSpeechSynthesisServer::PrimeL
       
   377 //
       
   378 // ----------------------------------------------------------------------------
       
   379 //
       
   380 void CSpeechSynthesisServer::PrimeL( const TDesC& aText, const RFile& aFile )
       
   381     {
       
   382     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::PrimeL" );
       
   383     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   384 
       
   385     iTtsUtility->SetOutputFileL( aFile ); 
       
   386     iTtsUtility->OpenDesL( aText ); 
       
   387     } 
       
   388     
       
   389 // ----------------------------------------------------------------------------
       
   390 // CSpeechSynthesisServer::Synthesize
       
   391 //
       
   392 // ----------------------------------------------------------------------------
       
   393 //
       
   394 void CSpeechSynthesisServer::Synthesize()
       
   395     {
       
   396     RUBY_DEBUG0( "CSpeechSynthesisServer::Synthesize" );
       
   397     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   398     
       
   399     iTtsUtility->Play();
       
   400     }
       
   401     
       
   402 // ----------------------------------------------------------------------------
       
   403 // CSpeechSynthesisServer::Stop
       
   404 //
       
   405 // ----------------------------------------------------------------------------
       
   406 //
       
   407 void CSpeechSynthesisServer::Stop()
       
   408     {
       
   409     RUBY_DEBUG0( "CSpeechSynthesisServer::Stop" );
       
   410 
       
   411     if ( iOpenTtsPlugin != KNullUid )
       
   412         {
       
   413         iTtsUtility->Stop();
       
   414         }
       
   415     }
       
   416     
       
   417 // ----------------------------------------------------------------------------
       
   418 // CSpeechSynthesisServer::Pause
       
   419 //
       
   420 // ----------------------------------------------------------------------------
       
   421 //
       
   422 void CSpeechSynthesisServer::Pause()
       
   423     {
       
   424     RUBY_DEBUG0( "CSpeechSynthesisServer::Pause" );
       
   425     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   426     
       
   427     iTtsUtility->Pause(); 
       
   428     }  
       
   429 
       
   430 // ----------------------------------------------------------------------------
       
   431 // CSpeechSynthesisServer::GetSupportedLanguagesL
       
   432 //
       
   433 // ----------------------------------------------------------------------------
       
   434 //
       
   435 void CSpeechSynthesisServer::GetSupportedLanguagesL( RArray<TLanguage>& aLanguages )
       
   436     {
       
   437     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::GetSupportedLanguagesL" );
       
   438     
       
   439     UpdateSynthesisConfigurationIfNeededL();
       
   440     
       
   441     TInt error( KErrNone );    
       
   442     TLinearOrder<TLanguage> order( LanguageOrder );
       
   443     
       
   444     for( TInt i( 0 ); i < iTtsVoiceConfigs.Count(); i++ )
       
   445         {
       
   446         // Add every language only once 
       
   447         error = aLanguages.InsertInOrder( iTtsVoiceConfigs[i].iLanguage, order );
       
   448         if ( error && error != KErrAlreadyExists )
       
   449             {
       
   450             User::Leave( error );
       
   451             }
       
   452         }
       
   453     }
       
   454     
       
   455 // ----------------------------------------------------------------------------
       
   456 // CSpeechSynthesisServer::GetSupportedVoicesL
       
   457 //
       
   458 // ----------------------------------------------------------------------------
       
   459 //
       
   460 void CSpeechSynthesisServer::GetSupportedVoicesL( TLanguage aLanguage, 
       
   461                                                   RArray<TVoice>& aVoices )
       
   462     {
       
   463     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::GetSupportedVoicesL" );
       
   464     CleanupClosePushL( aVoices );
       
   465     
       
   466     UpdateSynthesisConfigurationIfNeededL();
       
   467     
       
   468     TVoice voice;
       
   469     
       
   470     for( TInt i( 0 ); i < iTtsVoiceConfigs.Count(); i++ )
       
   471         {
       
   472         if ( iTtsVoiceConfigs[i].iLanguage == aLanguage )
       
   473             {
       
   474             voice.iLanguage     = iTtsVoiceConfigs[i].iLanguage;
       
   475             voice.iVoiceName    = iTtsVoiceConfigs[i].iVoiceName;
       
   476             voice.iSamplingRate = iTtsVoiceConfigs[i].iSamplingRate;
       
   477             
       
   478             aVoices.AppendL( voice );
       
   479             }
       
   480         }
       
   481     CleanupStack::Pop(); 
       
   482     }
       
   483  
       
   484 // ----------------------------------------------------------------------------
       
   485 // CSpeechSynthesisServer::SetVoiceL
       
   486 //
       
   487 // ----------------------------------------------------------------------------
       
   488 //
       
   489 void CSpeechSynthesisServer::SetVoiceL( TVoice aVoice, TInt aSpeakingRate )
       
   490     {
       
   491     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetVoiceL" );
       
   492     
       
   493     UpdateSynthesisConfigurationIfNeededL();
       
   494     
       
   495     TTtsStyle newStyle;
       
   496     newStyle.iLanguage = aVoice.iLanguage;
       
   497     newStyle.iVoice    = aVoice.iVoiceName;
       
   498     newStyle.iRate     = aSpeakingRate;
       
   499     newStyle.iNlp      = ETrue;  // Turn NLP flag on, only Klatt will use it. 
       
   500             
       
   501     TInt voiceIndex( KErrNotFound );
       
   502     const TInt count ( 
       
   503     iTtsVoiceConfigs.Count() );
       
   504     TInt i( 0 );
       
   505     
       
   506     while ( i < count && voiceIndex < 0 )
       
   507         {        
       
   508         if ( iTtsVoiceConfigs[i].iLanguage == aVoice.iLanguage )
       
   509             {
       
   510             if ( aVoice.iVoiceName.Length() > 0 )
       
   511                 {
       
   512                 if ( iTtsVoiceConfigs[i].iVoiceName == aVoice.iVoiceName )
       
   513                     {
       
   514                     voiceIndex = i;
       
   515                     }
       
   516                 }
       
   517             else
       
   518                 {
       
   519                 voiceIndex = i;
       
   520                 }
       
   521             }
       
   522         
       
   523         i++;
       
   524         }
       
   525 
       
   526     if ( voiceIndex >= 0 )
       
   527         {
       
   528         if ( iOpenTtsPlugin != iTtsVoiceConfigs[voiceIndex].iPluginUid )
       
   529             {
       
   530             iTtsUtility->Close();
       
   531             iOpenTtsPlugin = KNullUid;
       
   532         
       
   533             iTtsUtility->OpenPluginL( iTtsVoiceConfigs[voiceIndex].iPluginUid );
       
   534             iOpenTtsPlugin = iTtsVoiceConfigs[voiceIndex].iPluginUid;
       
   535             }
       
   536         
       
   537         iTtsUtility->SetDefaultStyleL( newStyle );
       
   538         }
       
   539     else
       
   540         {
       
   541         User::Leave( KErrNotFound );
       
   542         }
       
   543     }
       
   544 
       
   545 // ----------------------------------------------------------------------------
       
   546 // CSpeechSynthesisServer::SetVolume
       
   547 //
       
   548 // ----------------------------------------------------------------------------
       
   549 //
       
   550 void CSpeechSynthesisServer::SetVolume( TInt aVolume )
       
   551     {
       
   552     RUBY_DEBUG0( "CSpeechSynthesisServer::SetVolumeL" );
       
   553     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   554     
       
   555     iTtsUtility->SetVolume( aVolume );
       
   556     }
       
   557 
       
   558 // ----------------------------------------------------------------------------
       
   559 // CSpeechSynthesisServer::SetAudioPriorityL
       
   560 //
       
   561 // ----------------------------------------------------------------------------
       
   562 //
       
   563 void CSpeechSynthesisServer::SetAudioPriorityL( TInt aPriority, 
       
   564                                                 TInt aPreference )
       
   565     {
       
   566     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetAudioPriorityL" );
       
   567     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   568     
       
   569     iTtsUtility->SetPriority( aPriority, (TMdaPriorityPreference)aPreference );
       
   570     }
       
   571     
       
   572 // ----------------------------------------------------------------------------
       
   573 // CSpeechSynthesisServer::SetAudioOutputL
       
   574 //
       
   575 // ----------------------------------------------------------------------------
       
   576 //
       
   577 void CSpeechSynthesisServer::SetAudioOutputL( TInt aAudioOutput )
       
   578     {
       
   579     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetAudioOutput" );
       
   580     RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
       
   581     
       
   582     TMMFMessageDestinationPckg destination( iOpenTtsPlugin );
       
   583     CAudioOutput::TAudioOutputPreference output;
       
   584     
       
   585     switch ( aAudioOutput )
       
   586         {        
       
   587         case RSpeechSynthesis::ETtsOutputAll: 
       
   588             
       
   589             output = CAudioOutput::EAll;
       
   590             
       
   591             break;
       
   592 
       
   593         case RSpeechSynthesis::ETtsOutputNoOutput: 
       
   594             
       
   595             output = CAudioOutput::ENoOutput;
       
   596             
       
   597             break;
       
   598 
       
   599         case RSpeechSynthesis::ETtsOutputPrivate: 
       
   600             
       
   601             output = CAudioOutput::EPrivate;
       
   602             
       
   603             break;
       
   604 
       
   605         case RSpeechSynthesis::ETtsOutputPublic: 
       
   606             
       
   607             output = CAudioOutput::EPublic;
       
   608             
       
   609             break;
       
   610             
       
   611         default:
       
   612             
       
   613             output = CAudioOutput::ENoPreference;
       
   614         }
       
   615             
       
   616     TBuf8<2> data;
       
   617     data.AppendNum( output );    
       
   618 
       
   619     User::LeaveIfError( iTtsUtility->CustomCommandSync( destination, 
       
   620                                                         ETtsCustomCommandSetAudioOutput, 
       
   621                                                         data, KNullDesC8 ) );
       
   622     }
       
   623     
       
   624 // ----------------------------------------------------------------------------
       
   625 // CSpeechSynthesisServer::CustomCommand
       
   626 //
       
   627 // ----------------------------------------------------------------------------
       
   628 //
       
   629 TInt CSpeechSynthesisServer::CustomCommand( TInt aCommand, TInt aValue )
       
   630     {
       
   631     RUBY_DEBUG0( "" );
       
   632     
       
   633     TInt result( KErrNotReady );
       
   634     
       
   635     if ( iOpenTtsPlugin != KNullUid )
       
   636         {
       
   637         TMMFMessageDestinationPckg destination( iOpenTtsPlugin );
       
   638         
       
   639         TBuf8<16> command;
       
   640         command.AppendNum( aCommand );
       
   641         
       
   642         TBuf8<16> value;
       
   643         value.AppendNum( aValue );
       
   644     
       
   645         result = iTtsUtility->CustomCommandSync( destination, ETtsCustomCommandSetPluginParameter, 
       
   646                                                  command, value );
       
   647         }
       
   648     
       
   649     return result;
       
   650     }
       
   651     
       
   652 // ----------------------------------------------------------------------------
       
   653 // CSpeechSynthesisServer::IsVoiceValidL
       
   654 //
       
   655 // ----------------------------------------------------------------------------
       
   656 //
       
   657 TBool CSpeechSynthesisServer::IsVoiceValidL( const TVoice& aVoice )
       
   658     {
       
   659     RUBY_DEBUG0( "CSpeechSynthesisServer::IsVoiceValid" );
       
   660     
       
   661     UpdateSynthesisConfigurationIfNeededL();
       
   662     
       
   663     TBool found( EFalse );
       
   664     TInt index( 0 );
       
   665     TInt count( iTtsVoiceConfigs.Count() );
       
   666     
       
   667     while ( !found  && index < count )
       
   668         {        
       
   669         if ( iTtsVoiceConfigs[index].iLanguage == aVoice.iLanguage )
       
   670             {
       
   671             found = ETrue;
       
   672             
       
   673             if ( aVoice.iVoiceName.Length() > 0 &&
       
   674                  aVoice.iVoiceName != iTtsVoiceConfigs[index].iVoiceName )
       
   675                 {
       
   676                 // Voice name does not match
       
   677                 found = EFalse;
       
   678                 }
       
   679                 
       
   680             if ( aVoice.iSamplingRate != KErrNotFound && 
       
   681                  aVoice.iSamplingRate != iTtsVoiceConfigs[index].iSamplingRate )
       
   682                 {
       
   683                 // Sampling rate does not match
       
   684                 found = EFalse;
       
   685                 }
       
   686             }
       
   687         
       
   688         index++;
       
   689         }
       
   690 
       
   691     return found;
       
   692     }
       
   693     
       
   694 // ----------------------------------------------------------------------------
       
   695 // CSpeechSynthesisServer::McoConfigurationChanged
       
   696 // Some SIS package has been installed or removed
       
   697 // ----------------------------------------------------------------------------
       
   698 //
       
   699 void CSpeechSynthesisServer::McoConfigurationChanged()
       
   700     {
       
   701     RUBY_DEBUG0( "CSpeechSynthesisServer::McoConfigurationChanged" );
       
   702     
       
   703     iUpdateNeeded = ETrue;
       
   704     }
       
   705     
       
   706 // ----------------------------------------------------------------------------
       
   707 // CSpeechSynthesisServer::MapcCustomCommandEvent
       
   708 //
       
   709 // ----------------------------------------------------------------------------
       
   710 //
       
   711 void CSpeechSynthesisServer::MapcCustomCommandEvent( TInt /*aEvent*/, 
       
   712                                                      TInt /*aError*/ )
       
   713     {
       
   714     RUBY_ERROR0( "CSpeechSynthesisServer::MapcCustomCommandEvent" );
       
   715     
       
   716     // Not used
       
   717     }
       
   718     
       
   719 // ----------------------------------------------------------------------------
       
   720 // CSpeechSynthesisServer::MapcInitComplete
       
   721 //
       
   722 // ----------------------------------------------------------------------------
       
   723 //
       
   724 void CSpeechSynthesisServer::MapcInitComplete( TInt aError, 
       
   725         const TTimeIntervalMicroSeconds& aDuration )
       
   726     {
       
   727     RUBY_DEBUG1( "CSpeechSynthesisServer::MapcInitComplete [%x]", iSession );
       
   728     
       
   729     if ( iSession )
       
   730         {
       
   731         iSession->MsssInitComplete( aError, aDuration );
       
   732         }
       
   733     else
       
   734         {
       
   735         RUBY_ERROR1( "CSpeechSynthesisServer::MapcInitComplete - No session [%d]",
       
   736                      aError );
       
   737         }
       
   738     }
       
   739 
       
   740 // ----------------------------------------------------------------------------
       
   741 // CSpeechSynthesisServer::MapcPlayComplete
       
   742 //
       
   743 // ----------------------------------------------------------------------------
       
   744 //      
       
   745 void CSpeechSynthesisServer::MapcPlayComplete( TInt aError )
       
   746     {
       
   747     RUBY_DEBUG1( "CSpeechSynthesisServer::MapcPlayComplete [%x]", iSession );
       
   748     
       
   749     if ( iSession )
       
   750         {
       
   751         iSession->MsssPlayComplete( aError );
       
   752         }
       
   753     else
       
   754         {
       
   755         RUBY_ERROR1( "CSpeechSynthesisServer::MapcPlayComplete - No session [%d]",
       
   756                      aError );
       
   757         }
       
   758     }
       
   759 
       
   760 // ----------------------------------------------------------------------------
       
   761 // CSpeechSynthesisServer::ClosePlugin
       
   762 // 
       
   763 // ----------------------------------------------------------------------------
       
   764 //
       
   765 TInt CSpeechSynthesisServer::ClosePlugin( TAny* aAny )
       
   766     {
       
   767     CSpeechSynthesisServer* self = reinterpret_cast<CSpeechSynthesisServer*>( aAny );
       
   768 
       
   769     RUBY_DEBUG1( "Closing plugin %x", self->iOpenTtsPlugin );
       
   770     
       
   771     self->iPluginCloser->Cancel();
       
   772     
       
   773     self->iTtsUtility->Close();
       
   774     self->iOpenTtsPlugin = KNullUid;
       
   775     
       
   776     return KErrNone;
       
   777     }
       
   778 
       
   779 // ----------------------------------------------------------------------------
       
   780 // CSpeechSynthesisServer::PreviousSession
       
   781 // 
       
   782 // ----------------------------------------------------------------------------
       
   783 //
       
   784 const MSpeechSynthesisServerObserver* CSpeechSynthesisServer::PreviousSession()
       
   785     {
       
   786     RUBY_DEBUG1( "iPreviousSession = %x", iPreviousSession );
       
   787     
       
   788     return iPreviousSession;
       
   789     }
       
   790 
       
   791 // ----------------------------------------------------------------------------
       
   792 // CSpeechSynthesisServer::ClosePlugin
       
   793 // 
       
   794 // ----------------------------------------------------------------------------
       
   795 //
       
   796 void CSpeechSynthesisServer::ClosePlugin()
       
   797     {
       
   798     RUBY_DEBUG0( "" );
       
   799     
       
   800     iPluginCloser->Cancel();
       
   801     
       
   802     iTtsUtility->Close();
       
   803     iOpenTtsPlugin = KNullUid;
       
   804     }
       
   805         
       
   806 // ----------------------------------------------------------------------------
       
   807 // CSpeechSynthesisServer::NewSessionL
       
   808 // Create a new client session.
       
   809 // ----------------------------------------------------------------------------
       
   810 //
       
   811 CSession2* CSpeechSynthesisServer::NewSessionL( const TVersion& /*aVersion*/, 
       
   812                                                 const RMessage2& /*aMessage*/ ) const
       
   813     {
       
   814     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::NewSessionL" );
       
   815     
       
   816     return new( ELeave ) CSpeechSynthesisSession();
       
   817     }
       
   818 
       
   819 // ----------------------------------------------------------------------------
       
   820 // CSpeechSynthesisServer::CustomSecurityCheckL
       
   821 // Custom access policy check
       
   822 // ----------------------------------------------------------------------------
       
   823 //
       
   824 CPolicyServer::TCustomResult CSpeechSynthesisServer::CustomSecurityCheckL( 
       
   825     const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& aMissing )
       
   826     {
       
   827     RUBY_DEBUG_BLOCK( "" );
       
   828     
       
   829     CPolicyServer::TCustomResult result( CPolicyServer::EFail ); 
       
   830     
       
   831     if ( aMsg.Function() == ESetAudioOutput )
       
   832         {
       
   833         if ( aMsg.Int0() == RSpeechSynthesis::ETtsOutputAll && 
       
   834              !aMsg.HasCapability( ECapabilityWriteDeviceData, 
       
   835                                   __PLATSEC_DIAGNOSTIC_STRING("Missing WriteDeviceData") ) )
       
   836             {
       
   837             result = CPolicyServer::EFail;
       
   838             
       
   839             aMissing.iCaps = ECapabilityWriteDeviceData;
       
   840             }
       
   841         else
       
   842             {
       
   843             result = CPolicyServer::EPass;
       
   844             }
       
   845         }
       
   846     
       
   847     return result;
       
   848     }
       
   849 
       
   850 // ----------------------------------------------------------------------------
       
   851 // CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL
       
   852 // 
       
   853 // ----------------------------------------------------------------------------
       
   854 //
       
   855 void CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL()
       
   856     {
       
   857     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL" );
       
   858     
       
   859     if ( iUpdateNeeded )
       
   860         {
       
   861         RUBY_DEBUG0( "Update needed!" );
       
   862         
       
   863         if ( iSession )
       
   864             {
       
   865             RUBY_DEBUG0( "Cannot update - iSession not NULL" );
       
   866             }
       
   867         else            
       
   868             {
       
   869             UpdateSynthesisConfigurationL();
       
   870             
       
   871             iUpdateNeeded = EFalse;
       
   872             }
       
   873         }
       
   874     }
       
   875     
       
   876 // ----------------------------------------------------------------------------
       
   877 // CSpeechSynthesisServer::UpdateSynthesisConfigurationL
       
   878 // 
       
   879 // ----------------------------------------------------------------------------
       
   880 //
       
   881 void CSpeechSynthesisServer::UpdateSynthesisConfigurationL()
       
   882     {
       
   883     RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::UpdateSynthesisConfigurationL" );
       
   884     
       
   885     iPluginCloser->Cancel();
       
   886     
       
   887     RArray<TLanguage> languages;
       
   888     CleanupClosePushL( languages );
       
   889     
       
   890     RArray<TTtsStyle> ttsVoices;
       
   891     CleanupClosePushL( ttsVoices );
       
   892     
       
   893     TVoiceConfiguration cnfg;
       
   894     
       
   895     TBool defaultsVoiceSet( EFalse );
       
   896     
       
   897     // UI language is selected as a default language if it is supported 
       
   898     TLanguage defaultLanguage( User::Language() ); 
       
   899 
       
   900     RArray<TUid> ttsPlugins;
       
   901     CleanupClosePushL( ttsPlugins ); 
       
   902     
       
   903     // Plugins are listed in priority order (highest first)
       
   904     iTtsUtility->ListPluginsL( ttsPlugins );    
       
   905     iTtsVoiceConfigs.Reset();
       
   906     
       
   907     // Loop all plugins
       
   908     for ( TInt i( 0 ); i < ttsPlugins.Count(); i++  )
       
   909         {
       
   910         cnfg.iPluginUid = ttsPlugins[i];
       
   911         
       
   912         iTtsUtility->Close();
       
   913         iOpenTtsPlugin = KNullUid;
       
   914         
       
   915         iTtsUtility->OpenPluginL( ttsPlugins[i] );
       
   916         iOpenTtsPlugin = ttsPlugins[i];
       
   917         
       
   918         iTtsUtility->GetSupportedLanguagesL( languages );
       
   919 
       
   920         if ( i == 0 )
       
   921             {
       
   922             // Maximum volume is same for all plugins. 
       
   923             iDefaultMaxVolume = iTtsUtility->MaxVolume();
       
   924             iDefaultVolume = iDefaultMaxVolume / 2;
       
   925             }
       
   926 
       
   927         // Loop supported languages
       
   928         for ( TInt j( 0 ); j < languages.Count(); j++ )
       
   929             {
       
   930             cnfg.iLanguage = languages[j];
       
   931 
       
   932             iTtsUtility->GetSupportedVoicesL( languages[j], ttsVoices ); 
       
   933             
       
   934             // Loop supported voices
       
   935             for ( TInt k( 0 ); k < ttsVoices.Count(); k++ )
       
   936                 {
       
   937                 cnfg.iVoiceName    = ttsVoices[k].iVoice;
       
   938                 cnfg.iSamplingRate = ttsVoices[k].iSamplingRate;
       
   939                 
       
   940                 iTtsVoiceConfigs.AppendL( cnfg );
       
   941 
       
   942                 if ( !defaultsVoiceSet && cnfg.iLanguage == defaultLanguage )
       
   943                     {
       
   944                     // Default voice is not set yet -> set it now
       
   945                     defaultsVoiceSet = ETrue;
       
   946                     
       
   947                     iDefaultVoice.iLanguage     = cnfg.iLanguage;
       
   948                     iDefaultVoice.iVoiceName    = cnfg.iVoiceName;
       
   949                     iDefaultVoice.iSamplingRate = cnfg.iSamplingRate;
       
   950                     }
       
   951                 }
       
   952             
       
   953             ttsVoices.Reset();
       
   954             }
       
   955         
       
   956         languages.Reset();
       
   957         }
       
   958     
       
   959     CleanupStack::PopAndDestroy( &ttsPlugins );
       
   960     CleanupStack::PopAndDestroy( &ttsVoices );
       
   961     CleanupStack::PopAndDestroy( &languages );
       
   962     
       
   963     if ( !defaultsVoiceSet && iTtsVoiceConfigs.Count() > 0 )
       
   964         {
       
   965         iDefaultVoice.iLanguage     = iTtsVoiceConfigs[0].iLanguage;
       
   966         iDefaultVoice.iVoiceName    = iTtsVoiceConfigs[0].iVoiceName;
       
   967         iDefaultVoice.iSamplingRate = iTtsVoiceConfigs[0].iSamplingRate;
       
   968         } 
       
   969     
       
   970     if ( !iSession )
       
   971         {
       
   972         iPluginCloser->Start( KTtsPluginCloseWait, KTtsPluginCloseWait,
       
   973                               TCallBack( ClosePlugin, this ) );
       
   974         
       
   975         RUBY_DEBUG0( "iPluginCloser started" );
       
   976         }
       
   977     }
       
   978 
       
   979 // End of file