--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/speechsynthesis/client/src/speechsynthesis.cpp Thu Dec 17 08:46:30 2009 +0200
@@ -0,0 +1,574 @@
+/*
+* 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, client side code
+*
+*/
+
+
+// @todo Add better file write support to Klatt and HQ plugins
+// @todo Add support for lipsync information
+
+#include <e32svr.h>
+#include <f32file.h>
+#include <s32mem.h>
+#include <speechsynthesis.h>
+
+#include "speechsynthesisclientserver.h"
+
+// CONSTANTS
+
+const TInt KMajorVersion = 1;
+const TInt KMinorVersion = 0;
+const TInt KBuildNumber = 1;
+
+// ----------------------------------------------------------------------------
+// StartServer
+// Server startup code
+// ----------------------------------------------------------------------------
+//
+static TInt StartServer()
+ {
+ RProcess server;
+
+ TInt error = server.Create( KSpeechSynthesisServerImg, KNullDesC );
+
+ if ( !error )
+ {
+ // Server started
+ TRequestStatus status;
+ server.Rendezvous( status );
+
+ if ( status != KRequestPending )
+ {
+ server.Kill( KErrGeneral ); // Abort startup
+ }
+ else
+ {
+ server.Resume(); // Logon OK - start the server
+ }
+
+ User::WaitForRequest( status ); // Wait for start or death
+
+ error = ( server.ExitType() == EExitPanic ) ? KErrGeneral : status.Int();
+
+ // Close handle
+ server.Close();
+ }
+
+ return error;
+ }
+
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::RSpeechSynthesis
+// Constructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C RSpeechSynthesis::RSpeechSynthesis()
+ {
+ // Nothing
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::Open
+// Creates a session to server
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RSpeechSynthesis::Open()
+ {
+ const TInt KMessageSlots( 4 ); // 1 async, 1 sync, 1 cancel, 1 kernel
+
+ const TVersion requiredServerVersion( KMajorVersion,
+ KMinorVersion,
+ KBuildNumber );
+
+ // Try to create session with following parameters:
+ // 1) Name of the server
+ // 2) The lowest version of the server with which this client is compatible
+ // 3) The number of message slots
+ TInt error = CreateSession( KSpeechSynthesisServerName,
+ requiredServerVersion, KMessageSlots );
+
+ if ( error == KErrNotFound || error == KErrServerTerminated )
+ {
+ // Server not running -> try to start it
+ error = StartServer();
+
+ if ( error == KErrNone || error == KErrAlreadyExists )
+ {
+ // Server startup succeeded -> try to create session to it
+ error = CreateSession( KSpeechSynthesisServerName,
+ requiredServerVersion, KMessageSlots );
+
+ }
+ }
+
+ return error;
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::Close
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::Close()
+ {
+ RSessionBase::Close();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::InitialiseSynthesis
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::InitialiseSynthesis( const TDesC& aText,
+ TRequestStatus& aStatus )
+ {
+ if ( Handle() )
+ {
+ SendReceive( EPrime, TIpcArgs( &aText ), aStatus );
+ }
+ else
+ {
+ TRequestStatus *statusPointer = &aStatus;
+ User::RequestComplete( statusPointer, KErrBadHandle );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::InitialiseSynthesis
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::InitialiseSynthesis( const TDesC& aText,
+ const TFileName& aFileName,
+ TRequestStatus& aStatus )
+ {
+ TRAPD( error, DoInitialiseSynthesisL( aText, aFileName, aStatus ) );
+ if ( error )
+ {
+ TRequestStatus *statusPointer = &aStatus;
+ User::RequestComplete( statusPointer, error );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::InitialiseSynthesis
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::InitialiseSynthesis( const TDesC& aText,
+ TDes8& aDataBuffer,
+ TRequestStatus& aStatus )
+ {
+ if ( Handle() )
+ {
+ SendReceive( EPrimeStreamOutput, TIpcArgs( &aText, &aDataBuffer ), aStatus );
+ }
+ else
+ {
+ TRequestStatus *statusPointer = &aStatus;
+ User::RequestComplete( statusPointer, KErrBadHandle );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::Synthesise
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::Synthesise( TRequestStatus& aStatus )
+ {
+ if ( Handle() )
+ {
+ SendReceive( ESynthesise, aStatus );
+ }
+ else
+ {
+ TRequestStatus *statusPointer = &aStatus;
+ User::RequestComplete( statusPointer, KErrBadHandle );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::StopL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::StopL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( EStopSynthesis ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::PauseL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::PauseL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( EPauseSynthesis ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::DurationL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TTimeIntervalMicroSeconds RSpeechSynthesis::DurationL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TTimeIntervalMicroSeconds> pckg;
+
+ User::LeaveIfError( SendReceive( EGetDuration, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::GetLanguagesL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::GetLanguagesL( RArray<TLanguage>& aLanguages )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( EGetLanguageCount, TIpcArgs( &pckg ) ) );
+
+ const TInt languageCount( pckg() );
+
+ if ( languageCount > 0 )
+ {
+ const TInt tlanguageSize( sizeof(TLanguage) );
+
+ HBufC8* data = HBufC8::NewLC( languageCount * tlanguageSize );
+ TPtr8 data_ptr( data->Des() );
+
+ User::LeaveIfError( SendReceive( EGetLanguages, TIpcArgs( &data_ptr ) ) );
+
+ for ( TInt i( 0 ); i < languageCount; i++ )
+ {
+ TPtr8 tmp = data_ptr.MidTPtr( i * tlanguageSize, tlanguageSize );
+
+ const TLanguage* lang = (TLanguage*)tmp.Ptr();
+
+ aLanguages.AppendL( *lang );
+ }
+
+ CleanupStack::PopAndDestroy( data );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::GetVoicesL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::GetVoicesL( RArray<TVoice>& aVoices,
+ TLanguage aLanguage )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( EGetVoiceCount,
+ TIpcArgs( &pckg, aLanguage ) ) );
+
+ const TInt voiceCount( pckg() );
+
+ if ( voiceCount > 0 )
+ {
+ const TInt tvoiceSize( sizeof(TVoice) );
+
+ HBufC8* data = HBufC8::NewLC( voiceCount * tvoiceSize );
+ TPtr8 data_ptr( data->Des() );
+
+ User::LeaveIfError( SendReceive( EGetVoices, TIpcArgs( &data_ptr ) ) );
+
+ for ( TInt i( 0 ); i < voiceCount; i++ )
+ {
+ TPtr8 tmp = data_ptr.MidTPtr( i * tvoiceSize, tvoiceSize );
+
+ const TVoice* voice = (TVoice*)tmp.Ptr();
+
+ aVoices.AppendL( *voice );
+ }
+
+ CleanupStack::PopAndDestroy( data );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::VoiceL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TVoice RSpeechSynthesis::VoiceL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TVoice> pckg;
+
+ User::LeaveIfError( SendReceive( EVoice, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SetVoiceL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::SetVoiceL( const TVoice& aVoice )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TVoice> pckg = aVoice;
+
+ User::LeaveIfError( SendReceive( ESetVoice, TIpcArgs( &pckg ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::MaxSpeakingRateL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RSpeechSynthesis::MaxSpeakingRateL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( EMaxSpeakingRate, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SpeakingRateL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RSpeechSynthesis::SpeakingRateL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( ESpeakingRate, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SetSpeakingRateL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::SetSpeakingRateL( TInt aSpeakingRate )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( ESetSpeakingRate,
+ TIpcArgs( aSpeakingRate ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::MaxVolumeL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RSpeechSynthesis::MaxVolumeL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( EMaxVolume, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::VolumeL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RSpeechSynthesis::VolumeL()
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ TPckgBuf<TInt> pckg;
+
+ User::LeaveIfError( SendReceive( EVolume, TIpcArgs( &pckg ) ) );
+
+ return pckg();
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SetVolumeL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::SetVolumeL( TInt aVolume )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( ESetVolume, TIpcArgs( aVolume ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SetAudioPriorityL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::SetAudioPriorityL( TInt aPriority,
+ TInt aPreference )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( ESetAudioPriority,
+ TIpcArgs( aPriority, aPreference ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::SetAudioOutputL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::SetAudioOutputL( TTtsAudioOutput aAudioOutput )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( ESetAudioOutput, TIpcArgs( aAudioOutput ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::CustomCommandL
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RSpeechSynthesis::CustomCommandL( TInt aCommand, TInt aValue )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ User::LeaveIfError( SendReceive( ECustomCommand,
+ TIpcArgs( aCommand, aValue ) ) );
+ }
+
+// ----------------------------------------------------------------------------
+// RSpeechSynthesis::DoInitialiseSynthesisL
+//
+// ----------------------------------------------------------------------------
+//
+void RSpeechSynthesis::DoInitialiseSynthesisL( const TDesC& aText,
+ const TFileName& aFileName,
+ TRequestStatus& aStatus )
+ {
+ if ( Handle() == 0 )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ // @todo Add support for all supported audio formats
+ TFileName tmpName( aFileName );
+ tmpName.LowerCase();
+
+ TParse parser;
+ User::LeaveIfError( parser.Set( tmpName, NULL, NULL ) );
+
+ TPtrC extension = parser.Ext();
+
+ if ( extension != _L(".raw") )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ RFs fs;
+ RFile file;
+
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+ User::LeaveIfError( fs.ShareProtected() );
+
+ User::LeaveIfError( file.Replace( fs, aFileName, EFileWrite ) );
+ CleanupClosePushL( file );
+
+ TIpcArgs ipcArgs;
+ User::LeaveIfError( file.TransferToServer( ipcArgs, KFsHandleIndex, KFileHandleIndex ) );
+ User::LeaveIfError( SendReceive( ETransferFileHandle, ipcArgs ) );
+
+ CleanupStack::PopAndDestroy( &file );
+ CleanupStack::PopAndDestroy( &fs );
+
+ SendReceive( EPrimeFileOutput, TIpcArgs( &aText ), aStatus );
+ }
+
+// End of file