--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/speechsynthesis/server/src/speechsynthesisserver.cpp Wed Sep 01 12:29:17 2010 +0100
@@ -0,0 +1,979 @@
+/*
+* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Speech synthesis server
+*
+*/
+
+
+// INCLUDES
+
+#include <AudioOutput.h>
+#include <nssttscommon.h>
+
+#include "speechsynthesisserver.h"
+
+#include "speechsynthesisclientserver.h"
+#include "speechsynthesisserverutilities.h"
+#include "speechsynthesissession.h"
+
+#include "rubydebug.h"
+
+
+// CONSTANTS
+
+// Time to wait before tts plugin is closed if no activity detected.
+const TTimeIntervalMicroSeconds32 KTtsPluginCloseWait = 30000000; // 30 sec.
+
+// ----------------------------------------------------------------------------
+// RunServerL
+// Server startup code
+// Perform all server initialisation, in particular creation of the
+// scheduler and server and then run the scheduler
+// ----------------------------------------------------------------------------
+//
+static void RunServerL()
+ {
+ RUBY_DEBUG_BLOCK( "SpeechSynthesisServer: RunServerL" );
+
+ // Naming the server thread after the server helps to debug panics
+ User::LeaveIfError( User::RenameThread( KSpeechSynthesisServerName ) );
+
+ // Create and install the active scheduler we need
+ CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL( scheduler );
+ CActiveScheduler::Install( scheduler );
+
+ // Create the server (leave it on the cleanup stack)
+ CServer2* server = CSpeechSynthesisServer::NewLC();
+
+ // Initialisation complete, now signal the client
+ RProcess::Rendezvous( KErrNone );
+
+ RUBY_DEBUG0( "SpeechSynthesisServer: server fully running." );
+
+ // Ready to run
+ CActiveScheduler::Start();
+
+ RUBY_DEBUG0( "SpeechSynthesisServer: server closing." );
+
+ // Cleanup the server and scheduler
+ CleanupStack::PopAndDestroy( server );
+ CleanupStack::PopAndDestroy( scheduler );
+ }
+
+// ----------------------------------------------------------------------------
+// E32Main
+// Server process entry-point
+// ----------------------------------------------------------------------------
+//
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ RUBY_DEBUG0( "SpeechSynthesisServer: E32Main" );
+
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+
+ TInt error( KErrNoMemory );
+
+ if ( cleanup )
+ {
+ TRAP( error, RunServerL() );
+ delete cleanup;
+ }
+
+ __UHEAP_MARKEND;
+
+ return error;
+ }
+
+
+// ----------------------------------------------------------------------------
+// LanguageOrder
+// Used in CSpeechSynthesisServer::GetSupportedLanguagesL()
+// ----------------------------------------------------------------------------
+//
+static TInt LanguageOrder( const TLanguage& a, const TLanguage& b )
+ {
+ TInt result( 0 );
+
+ if ( a < b )
+ {
+ result = -1;
+ }
+ else if ( a > b )
+ {
+ result = 1;
+ }
+
+ return result;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::CSpeechSynthesisServer
+// Constructor
+// ----------------------------------------------------------------------------
+inline CSpeechSynthesisServer::CSpeechSynthesisServer() :
+ CPolicyServer( CActive::EPriorityStandard,
+ KSpeechSynthesisPolicy,
+ ESharableSessions ),
+ iOpenTtsPlugin( KNullUid ),
+ iSessionPriority( EMdaPriorityMin ),
+ iDefaultSpeakingRate( KTtsMaxSpeakingRate / 2 ),
+ iDefaultAudioPriority( EMdaPriorityNormal ),
+ iDefaultAudioPreference( EMdaPriorityPreferenceTimeAndQuality )
+ {
+ // Nothing
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::~CSpeechSynthesisServer
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CSpeechSynthesisServer::~CSpeechSynthesisServer()
+ {
+ delete iTtsUtility;
+ delete iShutdown;
+ delete iConfigurationListener;
+ delete iMMCListener;
+
+ iTtsVoiceConfigs.Close();
+
+ if ( iPluginCloser )
+ {
+ iPluginCloser->Cancel();
+ delete iPluginCloser;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::NewLC
+//
+// ----------------------------------------------------------------------------
+//
+CServer2* CSpeechSynthesisServer::NewLC()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::NewLC" );
+
+ CSpeechSynthesisServer* self = new(ELeave) CSpeechSynthesisServer();
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::ConstructL
+// 2nd phase construction - ensure the timer and server objects are running
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::ConstructL()
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ConstructL" );
+
+ StartL( KSpeechSynthesisServerName );
+
+ iTtsUtility = CTtsUtility::NewL( *this );
+ iTtsUtility->SetPriority( iDefaultAudioPriority,
+ (TMdaPriorityPreference)iDefaultAudioPreference );
+
+ // Create object for closing tts plugin when server has been idle for a while.
+ iPluginCloser = CPeriodic::NewL( CActive::EPriorityIdle );
+
+ // Listens for changes in SIS installations
+ iConfigurationListener = CConfigurationListener::NewL( *this );
+
+ // Listens insertions and removals of MMC.
+ iMMCListener = CMMCListener::NewL( *this );
+
+ UpdateSynthesisConfigurationL();
+
+ // Ensure that the server still exits even if the 1st client fails to connect
+ iShutdown = CShutdown::NewL();
+ iShutdown->Cancel();
+ iShutdown->Start();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::AddSession
+// A new session is being created
+// Cancel the shutdown timer if it was running
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::AddSession()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::AddSession" );
+
+ iSessionCount++;
+
+ iShutdown->Cancel();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::DropSession
+// A session is being destroyed
+// Start the shutdown timer if it is the last session.
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::DropSession()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::DropSession" );
+
+ iSessionCount--;
+
+ if ( iSessionCount == 0 )
+ {
+ iShutdown->Cancel();
+ iShutdown->Start();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::ReserveL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::ReserveL( MSpeechSynthesisServerObserver* aSession )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ReserveL" );
+
+ iPluginCloser->Cancel();
+
+ if ( !iSession || iSession == aSession )
+ {
+ // Session is not in use or it's reserved already for this session
+ iSession = aSession;
+ }
+ else
+ {
+ User::Leave( KErrInUse );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::ReserveL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::ReserveL( MSpeechSynthesisServerObserver* aSession,
+ TInt aPriority )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::ReserveL" );
+
+ iPluginCloser->Cancel();
+
+ if ( !iSession || iSession == aSession )
+ {
+ // Session is not in use or it's reserved already for this session
+ iSession = aSession;
+
+ iSessionPriority = aPriority;
+ }
+ else if ( aPriority > iSessionPriority )
+ {
+ Stop();
+
+ iSession->MsssOperationAborted();
+
+ iPreviousSession = iSession;
+ iSession = aSession;
+ iSessionPriority = aPriority;
+ }
+ else
+ {
+ User::Leave( KErrInUse );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::Release
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::Release( const MSpeechSynthesisServerObserver* aSession )
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::Release" );
+
+ if ( iSession == aSession )
+ {
+ iPreviousSession = iSession;
+ iSession = NULL;
+ iSessionPriority = EMdaPriorityMin;
+
+ TRAP_IGNORE( UpdateSynthesisConfigurationIfNeededL() );
+
+ iPluginCloser->Cancel();
+ iPluginCloser->Start( KTtsPluginCloseWait, KTtsPluginCloseWait,
+ TCallBack( ClosePlugin, this ) );
+
+ RUBY_DEBUG0( "iPluginCloser started" );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::GetDefaultSettingsL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::GetDefaultSettingsL( TVoice& aVoice,
+ TInt& aSpeakingRate, TInt& aMaxSpeakingRate,
+ TInt& aVolume, TInt& aMaxVolume,
+ TInt& aAudioPriority, TInt& aAudioPreference,
+ TInt& aAudioOutput )
+ {
+ UpdateSynthesisConfigurationIfNeededL();
+
+ aVoice = iDefaultVoice;
+ aSpeakingRate = iDefaultSpeakingRate;
+ aMaxSpeakingRate = KTtsMaxSpeakingRate;
+ aVolume = iDefaultVolume;
+ aMaxVolume = iDefaultMaxVolume;
+ aAudioPriority = iDefaultAudioPriority;
+ aAudioPreference = iDefaultAudioPreference;
+ aAudioOutput = RSpeechSynthesis::ETtsOutputDefault;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::GetDefaultVoiceL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::GetDefaultVoiceL( TVoice& aVoice )
+ {
+ UpdateSynthesisConfigurationIfNeededL();
+
+ aVoice = iDefaultVoice;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::PrimeL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::PrimeL( const TDesC& aText )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::PrimeL" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->OpenDesL( aText );
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::PrimeL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::PrimeL( const TDesC& aText, const RFile& aFile )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::PrimeL" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->SetOutputFileL( aFile );
+ iTtsUtility->OpenDesL( aText );
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::Synthesize
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::Synthesize()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::Synthesize" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->Play();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::Stop
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::Stop()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::Stop" );
+
+ if ( iOpenTtsPlugin != KNullUid )
+ {
+ iTtsUtility->Stop();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::Pause
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::Pause()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::Pause" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->Pause();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::GetSupportedLanguagesL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::GetSupportedLanguagesL( RArray<TLanguage>& aLanguages )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::GetSupportedLanguagesL" );
+
+ UpdateSynthesisConfigurationIfNeededL();
+
+ TInt error( KErrNone );
+ TLinearOrder<TLanguage> order( LanguageOrder );
+
+ for( TInt i( 0 ); i < iTtsVoiceConfigs.Count(); i++ )
+ {
+ // Add every language only once
+ error = aLanguages.InsertInOrder( iTtsVoiceConfigs[i].iLanguage, order );
+ if ( error && error != KErrAlreadyExists )
+ {
+ User::Leave( error );
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::GetSupportedVoicesL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::GetSupportedVoicesL( TLanguage aLanguage,
+ RArray<TVoice>& aVoices )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::GetSupportedVoicesL" );
+ CleanupClosePushL( aVoices );
+
+ UpdateSynthesisConfigurationIfNeededL();
+
+ TVoice voice;
+
+ for( TInt i( 0 ); i < iTtsVoiceConfigs.Count(); i++ )
+ {
+ if ( iTtsVoiceConfigs[i].iLanguage == aLanguage )
+ {
+ voice.iLanguage = iTtsVoiceConfigs[i].iLanguage;
+ voice.iVoiceName = iTtsVoiceConfigs[i].iVoiceName;
+ voice.iSamplingRate = iTtsVoiceConfigs[i].iSamplingRate;
+
+ aVoices.AppendL( voice );
+ }
+ }
+ CleanupStack::Pop();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::SetVoiceL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::SetVoiceL( TVoice aVoice, TInt aSpeakingRate )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetVoiceL" );
+
+ UpdateSynthesisConfigurationIfNeededL();
+
+ TTtsStyle newStyle;
+ newStyle.iLanguage = aVoice.iLanguage;
+ newStyle.iVoice = aVoice.iVoiceName;
+ newStyle.iRate = aSpeakingRate;
+ newStyle.iNlp = ETrue; // Turn NLP flag on, only Klatt will use it.
+
+ TInt voiceIndex( KErrNotFound );
+ const TInt count (
+ iTtsVoiceConfigs.Count() );
+ TInt i( 0 );
+
+ while ( i < count && voiceIndex < 0 )
+ {
+ if ( iTtsVoiceConfigs[i].iLanguage == aVoice.iLanguage )
+ {
+ if ( aVoice.iVoiceName.Length() > 0 )
+ {
+ if ( iTtsVoiceConfigs[i].iVoiceName == aVoice.iVoiceName )
+ {
+ voiceIndex = i;
+ }
+ }
+ else
+ {
+ voiceIndex = i;
+ }
+ }
+
+ i++;
+ }
+
+ if ( voiceIndex >= 0 )
+ {
+ if ( iOpenTtsPlugin != iTtsVoiceConfigs[voiceIndex].iPluginUid )
+ {
+ iTtsUtility->Close();
+ iOpenTtsPlugin = KNullUid;
+
+ iTtsUtility->OpenPluginL( iTtsVoiceConfigs[voiceIndex].iPluginUid );
+ iOpenTtsPlugin = iTtsVoiceConfigs[voiceIndex].iPluginUid;
+ }
+
+ iTtsUtility->SetDefaultStyleL( newStyle );
+ }
+ else
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::SetVolume
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::SetVolume( TInt aVolume )
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::SetVolumeL" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->SetVolume( aVolume );
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::SetAudioPriorityL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::SetAudioPriorityL( TInt aPriority,
+ TInt aPreference )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetAudioPriorityL" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ iTtsUtility->SetPriority( aPriority, (TMdaPriorityPreference)aPreference );
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::SetAudioOutputL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::SetAudioOutputL( TInt aAudioOutput )
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::SetAudioOutput" );
+ RUBY_ASSERT_DEBUG( iOpenTtsPlugin != KNullUid, User::Panic( KPanic, __LINE__ ) );
+
+ TMMFMessageDestinationPckg destination( iOpenTtsPlugin );
+ CAudioOutput::TAudioOutputPreference output;
+
+ switch ( aAudioOutput )
+ {
+ case RSpeechSynthesis::ETtsOutputAll:
+
+ output = CAudioOutput::EAll;
+
+ break;
+
+ case RSpeechSynthesis::ETtsOutputNoOutput:
+
+ output = CAudioOutput::ENoOutput;
+
+ break;
+
+ case RSpeechSynthesis::ETtsOutputPrivate:
+
+ output = CAudioOutput::EPrivate;
+
+ break;
+
+ case RSpeechSynthesis::ETtsOutputPublic:
+
+ output = CAudioOutput::EPublic;
+
+ break;
+
+ default:
+
+ output = CAudioOutput::ENoPreference;
+ }
+
+ TBuf8<2> data;
+ data.AppendNum( output );
+
+ User::LeaveIfError( iTtsUtility->CustomCommandSync( destination,
+ ETtsCustomCommandSetAudioOutput,
+ data, KNullDesC8 ) );
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::CustomCommand
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSpeechSynthesisServer::CustomCommand( TInt aCommand, TInt aValue )
+ {
+ RUBY_DEBUG0( "" );
+
+ TInt result( KErrNotReady );
+
+ if ( iOpenTtsPlugin != KNullUid )
+ {
+ TMMFMessageDestinationPckg destination( iOpenTtsPlugin );
+
+ TBuf8<16> command;
+ command.AppendNum( aCommand );
+
+ TBuf8<16> value;
+ value.AppendNum( aValue );
+
+ result = iTtsUtility->CustomCommandSync( destination, ETtsCustomCommandSetPluginParameter,
+ command, value );
+ }
+
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::IsVoiceValidL
+//
+// ----------------------------------------------------------------------------
+//
+TBool CSpeechSynthesisServer::IsVoiceValidL( const TVoice& aVoice )
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::IsVoiceValid" );
+
+ UpdateSynthesisConfigurationIfNeededL();
+
+ TBool found( EFalse );
+ TInt index( 0 );
+ TInt count( iTtsVoiceConfigs.Count() );
+
+ while ( !found && index < count )
+ {
+ if ( iTtsVoiceConfigs[index].iLanguage == aVoice.iLanguage )
+ {
+ found = ETrue;
+
+ if ( aVoice.iVoiceName.Length() > 0 &&
+ aVoice.iVoiceName != iTtsVoiceConfigs[index].iVoiceName )
+ {
+ // Voice name does not match
+ found = EFalse;
+ }
+
+ if ( aVoice.iSamplingRate != KErrNotFound &&
+ aVoice.iSamplingRate != iTtsVoiceConfigs[index].iSamplingRate )
+ {
+ // Sampling rate does not match
+ found = EFalse;
+ }
+ }
+
+ index++;
+ }
+
+ return found;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::McoConfigurationChanged
+// Some SIS package has been installed or removed
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::McoConfigurationChanged()
+ {
+ RUBY_DEBUG0( "CSpeechSynthesisServer::McoConfigurationChanged" );
+
+ iUpdateNeeded = ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::MapcCustomCommandEvent
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::MapcCustomCommandEvent( TInt /*aEvent*/,
+ TInt /*aError*/ )
+ {
+ RUBY_ERROR0( "CSpeechSynthesisServer::MapcCustomCommandEvent" );
+
+ // Not used
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::MapcInitComplete
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::MapcInitComplete( TInt aError,
+ const TTimeIntervalMicroSeconds& aDuration )
+ {
+ RUBY_DEBUG1( "CSpeechSynthesisServer::MapcInitComplete [%x]", iSession );
+
+ if ( iSession )
+ {
+ iSession->MsssInitComplete( aError, aDuration );
+ }
+ else
+ {
+ RUBY_ERROR1( "CSpeechSynthesisServer::MapcInitComplete - No session [%d]",
+ aError );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::MapcPlayComplete
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::MapcPlayComplete( TInt aError )
+ {
+ RUBY_DEBUG1( "CSpeechSynthesisServer::MapcPlayComplete [%x]", iSession );
+
+ if ( iSession )
+ {
+ iSession->MsssPlayComplete( aError );
+ }
+ else
+ {
+ RUBY_ERROR1( "CSpeechSynthesisServer::MapcPlayComplete - No session [%d]",
+ aError );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::ClosePlugin
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSpeechSynthesisServer::ClosePlugin( TAny* aAny )
+ {
+ CSpeechSynthesisServer* self = reinterpret_cast<CSpeechSynthesisServer*>( aAny );
+
+ RUBY_DEBUG1( "Closing plugin %x", self->iOpenTtsPlugin );
+
+ self->iPluginCloser->Cancel();
+
+ self->iTtsUtility->Close();
+ self->iOpenTtsPlugin = KNullUid;
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::PreviousSession
+//
+// ----------------------------------------------------------------------------
+//
+const MSpeechSynthesisServerObserver* CSpeechSynthesisServer::PreviousSession()
+ {
+ RUBY_DEBUG1( "iPreviousSession = %x", iPreviousSession );
+
+ return iPreviousSession;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::ClosePlugin
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::ClosePlugin()
+ {
+ RUBY_DEBUG0( "" );
+
+ iPluginCloser->Cancel();
+
+ iTtsUtility->Close();
+ iOpenTtsPlugin = KNullUid;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::NewSessionL
+// Create a new client session.
+// ----------------------------------------------------------------------------
+//
+CSession2* CSpeechSynthesisServer::NewSessionL( const TVersion& /*aVersion*/,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::NewSessionL" );
+
+ return new( ELeave ) CSpeechSynthesisSession();
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::CustomSecurityCheckL
+// Custom access policy check
+// ----------------------------------------------------------------------------
+//
+CPolicyServer::TCustomResult CSpeechSynthesisServer::CustomSecurityCheckL(
+ const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& aMissing )
+ {
+ RUBY_DEBUG_BLOCK( "" );
+
+ CPolicyServer::TCustomResult result( CPolicyServer::EFail );
+
+ if ( aMsg.Function() == ESetAudioOutput )
+ {
+ if ( aMsg.Int0() == RSpeechSynthesis::ETtsOutputAll &&
+ !aMsg.HasCapability( ECapabilityWriteDeviceData,
+ __PLATSEC_DIAGNOSTIC_STRING("Missing WriteDeviceData") ) )
+ {
+ result = CPolicyServer::EFail;
+
+ aMissing.iCaps = ECapabilityWriteDeviceData;
+ }
+ else
+ {
+ result = CPolicyServer::EPass;
+ }
+ }
+
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL()
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::UpdateSynthesisConfigurationIfNeededL" );
+
+ if ( iUpdateNeeded )
+ {
+ RUBY_DEBUG0( "Update needed!" );
+
+ if ( iSession )
+ {
+ RUBY_DEBUG0( "Cannot update - iSession not NULL" );
+ }
+ else
+ {
+ UpdateSynthesisConfigurationL();
+
+ iUpdateNeeded = EFalse;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSpeechSynthesisServer::UpdateSynthesisConfigurationL
+//
+// ----------------------------------------------------------------------------
+//
+void CSpeechSynthesisServer::UpdateSynthesisConfigurationL()
+ {
+ RUBY_DEBUG_BLOCK( "CSpeechSynthesisServer::UpdateSynthesisConfigurationL" );
+
+ iPluginCloser->Cancel();
+
+ RArray<TLanguage> languages;
+ CleanupClosePushL( languages );
+
+ RArray<TTtsStyle> ttsVoices;
+ CleanupClosePushL( ttsVoices );
+
+ TVoiceConfiguration cnfg;
+
+ TBool defaultsVoiceSet( EFalse );
+
+ // UI language is selected as a default language if it is supported
+ TLanguage defaultLanguage( User::Language() );
+
+ RArray<TUid> ttsPlugins;
+ CleanupClosePushL( ttsPlugins );
+
+ // Plugins are listed in priority order (highest first)
+ iTtsUtility->ListPluginsL( ttsPlugins );
+ iTtsVoiceConfigs.Reset();
+
+ // Loop all plugins
+ for ( TInt i( 0 ); i < ttsPlugins.Count(); i++ )
+ {
+ cnfg.iPluginUid = ttsPlugins[i];
+
+ iTtsUtility->Close();
+ iOpenTtsPlugin = KNullUid;
+
+ iTtsUtility->OpenPluginL( ttsPlugins[i] );
+ iOpenTtsPlugin = ttsPlugins[i];
+
+ iTtsUtility->GetSupportedLanguagesL( languages );
+
+ if ( i == 0 )
+ {
+ // Maximum volume is same for all plugins.
+ iDefaultMaxVolume = iTtsUtility->MaxVolume();
+ iDefaultVolume = iDefaultMaxVolume / 2;
+ }
+
+ // Loop supported languages
+ for ( TInt j( 0 ); j < languages.Count(); j++ )
+ {
+ cnfg.iLanguage = languages[j];
+
+ iTtsUtility->GetSupportedVoicesL( languages[j], ttsVoices );
+
+ // Loop supported voices
+ for ( TInt k( 0 ); k < ttsVoices.Count(); k++ )
+ {
+ cnfg.iVoiceName = ttsVoices[k].iVoice;
+ cnfg.iSamplingRate = ttsVoices[k].iSamplingRate;
+
+ iTtsVoiceConfigs.AppendL( cnfg );
+
+ if ( !defaultsVoiceSet && cnfg.iLanguage == defaultLanguage )
+ {
+ // Default voice is not set yet -> set it now
+ defaultsVoiceSet = ETrue;
+
+ iDefaultVoice.iLanguage = cnfg.iLanguage;
+ iDefaultVoice.iVoiceName = cnfg.iVoiceName;
+ iDefaultVoice.iSamplingRate = cnfg.iSamplingRate;
+ }
+ }
+
+ ttsVoices.Reset();
+ }
+
+ languages.Reset();
+ }
+
+ CleanupStack::PopAndDestroy( &ttsPlugins );
+ CleanupStack::PopAndDestroy( &ttsVoices );
+ CleanupStack::PopAndDestroy( &languages );
+
+ if ( !defaultsVoiceSet && iTtsVoiceConfigs.Count() > 0 )
+ {
+ iDefaultVoice.iLanguage = iTtsVoiceConfigs[0].iLanguage;
+ iDefaultVoice.iVoiceName = iTtsVoiceConfigs[0].iVoiceName;
+ iDefaultVoice.iSamplingRate = iTtsVoiceConfigs[0].iSamplingRate;
+ }
+
+ if ( !iSession )
+ {
+ iPluginCloser->Start( KTtsPluginCloseWait, KTtsPluginCloseWait,
+ TCallBack( ClosePlugin, this ) );
+
+ RUBY_DEBUG0( "iPluginCloser started" );
+ }
+ }
+
+// End of file