diff -r cad71a31b7fc -r e36f3802f733 srsf/speechsynthesis/client/src/speechsynthesis.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srsf/speechsynthesis/client/src/speechsynthesis.cpp Wed Sep 01 12:29:17 2010 +0100 @@ -0,0 +1,578 @@ +/* +* 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 +#include +#include +#include + +#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 pckg; + + User::LeaveIfError( SendReceive( EGetDuration, TIpcArgs( &pckg ) ) ); + + return pckg(); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::GetLanguagesL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C void RSpeechSynthesis::GetLanguagesL( RArray& aLanguages ) + { + CleanupClosePushL( aLanguages ); + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf 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 ); + } + CleanupStack::Pop(); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::GetVoicesL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C void RSpeechSynthesis::GetVoicesL( RArray& aVoices, + TLanguage aLanguage ) + { + CleanupClosePushL( aVoices ); + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf 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 ); + } + CleanupStack::Pop(); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::VoiceL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C TVoice RSpeechSynthesis::VoiceL() + { + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf 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 pckg = aVoice; + + User::LeaveIfError( SendReceive( ESetVoice, TIpcArgs( &pckg ) ) ); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::MaxSpeakingRateL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt RSpeechSynthesis::MaxSpeakingRateL() + { + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf pckg; + + User::LeaveIfError( SendReceive( EMaxSpeakingRate, TIpcArgs( &pckg ) ) ); + + return pckg(); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::SpeakingRateL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt RSpeechSynthesis::SpeakingRateL() + { + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf 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 pckg; + + User::LeaveIfError( SendReceive( EMaxVolume, TIpcArgs( &pckg ) ) ); + + return pckg(); + } + +// ---------------------------------------------------------------------------- +// RSpeechSynthesis::VolumeL +// +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt RSpeechSynthesis::VolumeL() + { + if ( Handle() == 0 ) + { + User::Leave( KErrBadHandle ); + } + + TPckgBuf 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