diff -r cad71a31b7fc -r e36f3802f733 srsf/sisrscontrollerplugin/src/sicontrollerplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srsf/sisrscontrollerplugin/src/sicontrollerplugin.cpp Wed Sep 01 12:29:17 2010 +0100 @@ -0,0 +1,3929 @@ +/* +* Copyright (c) 2004-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: This is the main implementation of the SI Controller Plugin. +* Finite State Machine is implemented here. +* +*/ + + +// INCLUDE FILES +#include +#include + +#include +#include + +#include "sicontrollerplugin.h" +#include "sicontrollerplugininterface.h" +#include "sidatabase.h" + +#include "siresourcehandler.h" +#include "asrplugindataloader.h" + +#include "sigrammardb.h" +#include "silexicondb.h" +#include "simodelbankdb.h" + +#include "rubydebug.h" + +#ifdef __SINDE_TRAINING +#include "sindetraining.h" +#endif // __SINDE_TRAINING + +// Package types for general & language specific TTP data + +// CONSTANTS + +// Message types used in RunL +//const TInt KAddPronunciation = 1; // Commented out to remove "not referenced" warning +const TInt KAddRule = 2; +const TInt KCreateGrammar = 3; +const TInt KCreateLexicon = 4; +const TInt KCreateModelBank = 5; +const TInt KGetAllClientGrammarIDs = 6; +const TInt KGetAllClientLexiconIDs = 7; +const TInt KGetAllClientModelBankIDs = 8; +const TInt KGetAllGrammarIDs = 9; +const TInt KGetAllLexiconIDs = 10; +const TInt KGetAllModelBankIDs = 11; +const TInt KGetAllModelIDs = 12; +const TInt KGetAllPronunciationIDs = 13; +const TInt KGetAllRuleIDs = 14; +const TInt KGetAvailableStorage = 15; +const TInt KGetModelCount = 16; +const TInt KGetRuleValidity = 17; +const TInt KGetUtteranceDuration = 18; +const TInt KLoadGrammar = 19; +const TInt KLoadLexicon = 20; +const TInt KLoadModels = 21; +const TInt KPlayUtterance = 22; +const TInt KRecognize = 23; +const TInt KRecord = 24; +const TInt KRemoveGrammar = 25; +const TInt KRemoveLexicon = 26; +const TInt KRemoveModelBank = 27; +const TInt KRemoveModel = 28; +const TInt KRemovePronunciation = 29; +const TInt KRemoveRule = 30; +const TInt KTrain = 31; +const TInt KUnloadRule = 32; + +// SI only functionalities +const TInt KAdapt = 33; +//const TInt KSIAddPronunciation = 34; // Commented out to remove "not referenced" warning +const TInt KAddRuleVariant = 35; +//const TInt KAddVoiceTag = 36; // Commented out to remove "not referenced" warning +const TInt KAddVoiceTags = 37; +const TInt KCreateRule = 38; +//const TInt KSIRecognize = 39; // Commented out to remove "not referenced" warning +const TInt KEndRecord = 40; +const TInt KUnloadGrammar = 41; +//const TInt KUpdateGrammarAndLexicon = 42; // Commented out to remove "not referenced" warning +const TInt KGetPronunciationCount = 43; +const TInt KGetRuleCount = 44; +const TInt KRemoveRules = 45; + +//const TInt KAddSIPronunciation = 43; // Commented out to remove "not referenced" warning +//const TInt KAddOneSIPronunciation = 44; // Commented out to remove "not referenced" warning + +#ifdef __SINDE_TRAINING +// SINDE voice tags creation +const TInt KAddSindeVoiceTags = 46; +//const TInt KAddSindeVoiceTag = 47; // Commented out to remove "not referenced" warning +#endif // __SINDE_TRAINING + +const TInt KPreStartSampling = 48; + +// Define this if SINDE lexicon optimization is on +#define __SIND_LEXICON_OPT + +// Secure ID of voice commands application process +_LIT_SECURE_ID( KVoiceCommandsAppUid, 0x101f8555 ); + +// ============================= LOCAL FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// Panic +// User panic when an unrecoverable error occurs. +// Returns: - +// ----------------------------------------------------------------------------- +// +void Panic( TInt aPanicCode ) // Panic code + { + _LIT( KSDControllerPanicCategory, "SIControllerPlugin" ); + User::Panic( KSDControllerPanicCategory, aPanicCode ); + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CSIControllerPlugin +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CSIControllerPlugin::CSIControllerPlugin( CSIControllerPluginInterface& aControllerIf ) + : CActive( EPriorityLess ), + iState( ESiPluginIdle ), + iControllerIf( aControllerIf ), + iClientRegistered( EFalse ), + iGrammarID( 0 ), + iDataLoader( NULL ) + { + RUBY_DEBUG0( "CSIControllerPlugin::CSIControllerPlugin" ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::ConstructL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::ConstructL" ); + + iResourceHandler = CSIResourceHandler::NewL(); + + // Data loader + iDataLoader = CDataLoader::NewL( *(iResourceHandler->iDataFilenamePrefix), + *(iResourceHandler->iDataFilenameSeperator), + *(iResourceHandler->iDataFilenamePostfix ) ); + + TFileName dbFileName( *(iResourceHandler->iDbFileName )); + + // Database instances + iSIDatabase = CSIDatabase::NewL( dbFileName ); + RDbNamedDatabase& database = iSIDatabase->SIDatabase(); + RDbs& dbSession = iSIDatabase->DbSession(); + TInt drive = iSIDatabase->DbDrive(); + iSIGrammarDB = CSIGrammarDB::NewL( database, dbSession, drive ); + iSILexiconDB = CSILexiconDB::NewL( database, dbSession, drive ); + iSIModelBankDB = CSIModelBankDB::NewL( database, dbSession, drive ); + + iSIDatabase->BeginTransactionL(); + + if ( !( iSIDatabase->DoesLockTableExistL() ) ) + { + iSIDatabase->CreateLockTableL(); + } + + // Need to create all 3 ID tables at single transaction + + + // Create tables if they don't already exist + if ( !( iSIDatabase->DoesModelBankTableExistL() ) ) + { + iSIModelBankDB->CreateIDTableL(); + } + + if ( !( iSIDatabase->DoesLexiconTableExistL() ) ) + { + iSILexiconDB->CreateIDTableL(); + } + + if ( !( iSIDatabase->DoesGrammarTableExistL() ) ) + { + iSIGrammarDB->CreateIDTableL(); + } + + iSIDatabase->CommitChangesL( ETrue ); + + + iSITtpWordList = CSITtpWordList::NewL(); + + iDevASR = CDevASR::NewL( *this ); + + RUBY_DEBUG2( "[%d] CSIControllerPlugin::ConstructL - DevASR[%d]", this, iDevASR ); + +#ifdef __SINDE_TRAINING + iSindeTrainer = CSindeTrainer::NewL( *iDevASR, iControllerIf, *this, + *iSIDatabase, *iSIGrammarDB, *iSILexiconDB ); +#endif // __SINDE_TRAINING + + // Add active object to active scheduler + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSIControllerPlugin* CSIControllerPlugin::NewL( CSIControllerPluginInterface& aControllerIf ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::NewL" ); + CSIControllerPlugin* self = new( ELeave ) CSIControllerPlugin( aControllerIf ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::~CSIControllerPlugin +// Destructor +// ----------------------------------------------------------------------------- +// +CSIControllerPlugin::~CSIControllerPlugin() + { + RUBY_DEBUG0( "CSIControllerPlugin::~CSIControllerPlugin" ); + + RThread().SetPriority( EPriorityNormal ); + + Cancel(); + + // if there is any outstanding request, cancel it. + if ( iDevASR ) + { + iDevASR->Cancel(); + } + + delete iDevASR; + delete iResourceHandler; + delete iSIGrammarDB; + delete iSILexiconDB; // Handled by Grcompiler + delete iSIModelBankDB; + delete iDataLoader; + + delete iSIDatabase; + delete iSICompiledGrammarRecompile; + + iMaxNPronunsForWord.Close(); + delete iSITtpWordList; + +#ifdef __SINDE_TRAINING + delete iSindeTrainer; +#endif // __SINDE_TRAINING + + if ( iTrainArrays != NULL ) + { + iTrainArrays->ResetAndDestroy(); + iTrainArrays->Close(); + delete iTrainArrays; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddPronunciationL +// Calls the lexicon database handler to add a new pronunciation into the lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddPronunciationL( TSILexiconID /*aLexiconID*/, + TSIModelBankID /*aModelBankID*/, + const TDesC8& /*aPronunciationPr*/, + TSIPronunciationID& /*aPronunciationID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddPronunciationL 1" ); + User::Leave( KErrNotSupported ); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddPronunciationL +// Calls the lexicon database handler to add a new pronunciation into the lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddPronunciationL( TSILexiconID /*aLexiconID*/, + TSIModelBankID /*aModelBankID*/, + TSIModelID /*aModelID*/, + TSIPronunciationID& /*aPronunciationID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddPronunciationL 2" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::SDLexiconL +// ----------------------------------------------------------------------------- +// +#ifdef DEVASR_KEEP_SD +CSDLexicon* CSIControllerPlugin::SDLexiconL( TSILexiconID anID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::SDLexiconL" ); + + User::Leave( KErrNotSupported ); + return NULL; + } +#endif + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddRuleL +// Calls the grammar database handler to add a new rule into the grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddRuleL( TSIGrammarID aGrammarID, + TSILexiconID aLexiconID, + TSIPronunciationID aPronunciationID, + TSIRuleID& aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddRuleL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KAddRule; + iGrammarID = aGrammarID; + iLexiconID = aLexiconID; + iPronunciationID = aPronunciationID; + iRuleIDPtr = &aRuleID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleAddRule +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleAddRuleL( TSIGrammarID /*aGrammarID*/, + TSILexiconID /*aLexiconID*/, + TSIPronunciationID /*aPronunciationID*/, + TSIRuleID& /*aRuleID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleAddRuleL" ); + + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::Cancel +// Cancels the current activity and returns the plugin to Idle state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::Cancel() + { + RUBY_DEBUG1( "CSIControllerPlugin::Cancel (State=%d)", iState ); + + this->iSIDatabase->Rollback(); + switch ( iState ) + { + case ESdPluginTrain: + iDevASR->Cancel(); + + TRAP_IGNORE( + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->Reset(); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAP_IGNORE + + break; + + case ESiPluginRecognize: + iDevASR->Cancel(); + iState = ESiPluginRecognize; + break; + case ESiPluginTrainText: +#ifdef __SINDE_TRAINING + case ESiPluginTrainSinde: +#endif // __SINDE_TRAINING + iDevASR->Cancel(); + iState = ESiPluginIdle; + break; + case ESiPluginPlay: + iDevASR->Cancel(); + break; + + case ESiPluginIdle: + // Nothing to cancel + break; + + default: + // Unknown state - should never be here + break; + } + + // Cancel the active object + CActive::Cancel(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CommitChangesL +// Commits (saves) all database changes since the last commit request. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::CommitChangesL( TBool aCommit ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::CommitChangesL" ); + iSIDatabase->CommitChangesL( aCommit ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateGrammarL +// Calls the grammar database handler to create a new grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::CreateGrammarL( TSIGrammarID& aGrammarID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::CreateGrammarL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KCreateGrammar; + iGrammarIDPtr = &aGrammarID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleCreateGrammarL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleCreateGrammarL( TSIGrammarID& aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleCreateGrammarL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + + // update model banks if they are not valid anymore + RArray modelBankIDs; + CleanupClosePushL( modelBankIDs ); + iSIModelBankDB->GetAllClientModelBankIDsL( iClientUid, modelBankIDs ); + for ( TInt i(0); i < modelBankIDs.Count(); i++ ) + { + iSIModelBankDB->UpdateModelBankIfInvalidL( modelBankIDs[i] ); + } + CleanupStack::PopAndDestroy( &modelBankIDs ); + aGrammarID = iSIGrammarDB->CreateGrammarL(iClientUid); + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateLexiconL +// Calls the lexicon database handler to create a new lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::CreateLexiconL( TSILexiconID& aLexiconID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::CreateLexiconL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KCreateLexicon; + iLexiconIDPtr = &aLexiconID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleCreateLexiconL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleCreateLexiconL( TSILexiconID& aLexiconID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleCreateLexiconL"); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + aLexiconID = iSILexiconDB->CreateLexiconL(iClientUid); + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateModelBankL +// Calls the model database handler to create a new model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::CreateModelBankL( TSIModelBankID& aModelBankID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::CreateModelBankL"); + + if ( IsActive() ) + { + User::Leave(KErrServerBusy); + } + iRequestFunction = KCreateModelBank; + iModelBankIDPtr = &aModelBankID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleCreateModelBankL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleCreateModelBankL( TSIModelBankID& aModelBankID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleCreateModelBankL"); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + aModelBankID = iSIModelBankDB->CreateModelBankL(iClientUid); + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + User::Leave(KErrAsrNotRegisted); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::EndRecSessionL +// Ends recognition session and releases resources. If not in recognition state, +// no action is taken. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::EndRecSessionL() + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::EndRecSessionL"); + + switch ( iState ) + { + case ESiPluginRecognize: + iDevASR->EndRecSession(); + // Save the changes during model adaption. + iSIDatabase->CommitChangesL( ETrue ); + RecognitionReset(); + break; + case ESiPluginIdle: + // Ignore if already Idle + break; + default: + // Wrong state + User::Leave( KErrNotReady ); + break; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::ActivateGrammarL +// Activate the grammar for the recognition +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::ActivateGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::ActivateGrammarL"); + iDevASR->ActivateGrammarL(aGrammarID); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::DeactivateGrammarL +// Deactivate the grammar for the recognition +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::DeactivateGrammarL(TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::DeactivateGrammarL"); + iDevASR->DeactivateGrammarL(aGrammarID); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllClientGrammarIDsL +// Returns all grammar Ids that belong to the current client. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllClientGrammarIDsL( RArray& aGrammarIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllClientGrammarIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllClientGrammarIDs; + + iGrammarIDs = &aGrammarIDs; + + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllClientGrammarIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllClientGrammarIDsL( RArray& aGrammarIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllClientGrammarIDsL"); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->GetAllClientGrammarIDsL(iClientUid, aGrammarIDs); + iSIDatabase->CommitChangesL( EFalse ); + + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllClientLexiconIDsL +// Returns all lexicon Ids that belong to the current client. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllClientLexiconIDsL( RArray& aLexiconIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllClientLexiconIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllClientLexiconIDs; + iLexiconIDs = &aLexiconIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllClientLexiconIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllClientLexiconIDsL( RArray& aLexiconIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetAllClientLexiconIDsL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSILexiconDB->GetAllClientLexiconIDsL( iClientUid, aLexiconIDs ); + iSIDatabase->CommitChangesL( EFalse ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllClientModelBankIDsL +// Returns all model bank Ids that belong to the current client. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllClientModelBankIDsL( RArray& aModelBankIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllClientModelBankIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllClientModelBankIDs; + iModelBankIDs = &aModelBankIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllClientModelBankIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllClientModelBankIDsL( RArray& aModelBankIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetAllClientModelBankIDsL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->GetAllClientModelBankIDsL( iClientUid, aModelBankIDs ); + iSIDatabase->CommitChangesL( EFalse ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllGrammarIDsL +// Returns all grammar Ids that exist (for all clients). +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllGrammarIDsL( RArray& aGrammarIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetAllGrammarIDsL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllGrammarIDs; + iGrammarIDs = &aGrammarIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllGrammarIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllGrammarIDsL( RArray& aGrammarIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllGrammarIDsL"); + + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->GetAllGrammarIDsL(aGrammarIDs); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllLexiconIDsL +// Returns all lexicon Ids that exist (for all clients). +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllLexiconIDsL( RArray& aLexiconIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllLexiconIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllLexiconIDs; + iLexiconIDs = &aLexiconIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllLexiconIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllLexiconIDsL( RArray& aLexiconIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllLexiconIDsL"); + + iSIDatabase->BeginTransactionL(); + iSILexiconDB->GetAllLexiconIDsL(aLexiconIDs); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllModelBankIDsL +// Returns all model bank Ids that exist (for all clients). +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllModelBankIDsL( RArray& aModelBankIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetAllModelBankIDsL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllModelBankIDs; + iModelBankIDs = &aModelBankIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllModelBankIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllModelBankIDsL( RArray& aModelBankIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllModelBankIDsL"); + + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->GetAllModelBankIDsL( aModelBankIDs ); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllModelIDsL +// Calls the model database handler to get all model IDs in the model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllModelIDsL( TSIModelBankID aModelBankID, + RArray& aModelIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetAllModelIDsL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllModelIDs; + iModelBankID = aModelBankID; + iModelIDs = &aModelIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllModelIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllModelIDsL( TSIModelBankID aModelBankID, + RArray& aModelIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetAllModelIDsL" ); + + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->GetAllModelIDsL(aModelBankID, aModelIDs); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllPronunciationIDsL +// Calls the lexicon database handler to get all pronunciation IDs in the lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllPronunciationIDsL( TSILexiconID aLexiconID, + RArray& aPronunciationIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllPronunciationIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllPronunciationIDs; + iLexiconID = aLexiconID; + iPronunciationIDs = &aPronunciationIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllPronunciationIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllPronunciationIDsL( TSILexiconID aLexiconID, + RArray& aPronunciationIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllPronunciationIDsL"); + + iSIDatabase->BeginTransactionL(); + iSILexiconDB->GetAllPronunciationIDsL(aLexiconID, aPronunciationIDs); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAllRuleIDsL +// Calls the grammar database handler to get all rule IDs in the grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAllRuleIDsL( TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAllRuleIDsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAllRuleIDs; + iGrammarID = aGrammarID; + iRuleIDs = &aRuleIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAllRuleIDsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAllRuleIDsL( TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAllRuleIDsL"); + + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->GetAllRuleIDsL(aGrammarID, aRuleIDs); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetAvailableStorageL +// Calculates the available number of models that can be trained by subtracting +// the current total from the system defined max. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetAvailableStorageL( TInt& aCount ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetAvailableStorageL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetAvailableStorage; + iCountPtr = &aCount; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetAvailableStorageL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetAvailableStorageL( TInt& aCount ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetAvailableStorageL"); + + iSIDatabase->BeginTransactionL(); + TInt count = iSIModelBankDB->AllModelCountL(); + iSIDatabase->CommitChangesL( EFalse ); + + if ( count > iResourceHandler->iMaxModelsSystem ) + { + aCount = 0; + } + else + { + aCount = iResourceHandler->iMaxModelsSystem - count; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetEnginePropertiesL +// Returns the current recognition engine properties. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetEnginePropertiesL( const RArray& aPropertyId, + RArray& aPropertyValue ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetEnginePropertiesL" ); + + for ( TInt index = 0; index < aPropertyId.Count(); index++ ) + { + switch( aPropertyId[index] ) + { + case KModelStorageCapacity: + aPropertyValue.Append( iResourceHandler->iMaxModelsSystem ); + break; + + case KMaxLoadableModels: + aPropertyValue.Append( iResourceHandler->iMaxModelsPerBank ); + break; + + default: + aPropertyValue.Append( KErrNotSupported ); + break; + } + } + + iDevASR->GetEnginePropertiesL( aPropertyId, aPropertyValue ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetModelCountL +// Calls the model database handler for the number of models in a model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetModelCountL( TSIModelBankID aModelBankID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetModelCountL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetModelCount; + iModelBankID = aModelBankID; + iCountPtr = &aCount; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetModelCountL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetModelCountL( TSIModelBankID aModelBankID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetModelCountL" ); + + iSIDatabase->BeginTransactionL(); + aCount = iSIModelBankDB->ModelCountL( aModelBankID ); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetPronunciationCountL +// Calls the model database handler for the number of Pronunciation in a lexicon +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetPronunciationCountL( TSILexiconID aLexiconID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetPronunciationCountL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetPronunciationCount; + iLexiconID = aLexiconID; + iCountPtr = &aCount; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetPronunciationCountL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetPronunciationCountL( TSIModelBankID aLexiconID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetPronunciationCountL" ); + + iSIDatabase->BeginTransactionL(); + aCount = iSILexiconDB->PronunciationCountL( aLexiconID ); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetRuleCountL +// Calls the model database handler for the number of Pronunciation in a lexicon +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetRuleCountL( TSIGrammarID aGrammarID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetRuleCountL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetRuleCount; + iGrammarID = aGrammarID; + iCountPtr = &aCount; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetRuleCountL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetRuleCountL( TSIGrammarID aGrammarID, + TInt& aCount ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetRuleCountL"); + + iSIDatabase->BeginTransactionL(); + aCount = iSIGrammarDB->RuleCountL(aGrammarID); + iSIDatabase->CommitChangesL( EFalse ); + } + + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetRuleValidityL +// Calls the grammar database handler to see if the rule exists in the specified +// grammar. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetRuleValidityL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID, + TBool& aValid ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::GetRuleValidityL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetRuleValidity; + iGrammarID = aGrammarID; + iRuleID = aRuleID; + iValidPtr = &aValid; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetRuleValidityL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetRuleValidityL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID, + TBool& aValid ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleGetRuleValidityL"); + + iSIDatabase->BeginTransactionL(); + aValid = iSIGrammarDB->IsRuleValidL(aGrammarID, aRuleID); + iSIDatabase->CommitChangesL( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::GetUtteranceDurationL +// Calls the model database handler to get the duration of an utterance. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::GetUtteranceDurationL( TSIModelBankID aModelBankID, + TSIModelID aModelID, + TTimeIntervalMicroSeconds32& aDuration ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::GetUtteranceDurationL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KGetUtteranceDuration; + iModelBankID = aModelBankID; + iModelID = aModelID; + iDurationPtr = &aDuration; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleGetUtteranceDurationL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleGetUtteranceDurationL( TSIModelBankID /*aModelBankID*/, + TSIModelID /*aModelID*/, + TTimeIntervalMicroSeconds32& /*aDuration*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleGetUtteranceDurationL" ); + User::Leave( KErrNotSupported ); + } + + + // ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandlePlayUtteranceL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandlePlayUtteranceL( TSIModelBankID /*aModelBankID*/, + TSIModelID /*aModelID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandlePlayUtteranceL" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::LoadEngineParametersL +// Loads the specified recognizer parameter(s). These parameters are used to +// alter the recognizer's default parameters. The parameters are specified as +// attribute and value pairs. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::LoadEngineParametersL( const RArray& aParameterId, + const RArray& aParameterValue ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::LoadEngineParametersL" ); + iDevASR->LoadEngineParametersL( aParameterId, aParameterValue ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::LoadGrammarL +// Requests the grammar database handler for a grammar object to be loaded into +// the recognizer for recognition purpose. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::LoadGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::LoadGrammarL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + + iRequestFunction = KLoadGrammar; + iGrammarID = aGrammarID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleLoadGrammarL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleLoadGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleLoadGrammarL" ); + + if ( iState == ESiPluginRecognize ) + { + const CSICompiledGrammar* grammar = NULL; + // iGrammarDB keeps a reference to the grammar object so we don't + // have to push it onto a cleanupstack. + + iSIDatabase->BeginTransactionL(); + grammar = iSIGrammarDB->LoadGrammarL(aGrammarID); + iSIDatabase->CommitChangesL( EFalse ); + + iDevASR->LoadGrammar( *grammar ); + } + else + { + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::LoadLexiconL +// Requests the lexicon database handler for a lexicon object to be loaded into +// the recognizer for recognition purpose. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::LoadLexiconL( TSILexiconID aLexiconID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::LoadLexiconL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KLoadLexicon; + iLexiconID = aLexiconID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleLoadLexiconL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleLoadLexiconL( TSILexiconID aLexiconID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleLoadLexiconL" ); + + if ( iState == ESiPluginRecognize ) + { + const CSILexicon* lexicon = NULL; + // iGrammarDB keeps a reference to the grammar object so we don't + // have to push it onto a cleanupstack. + + iSIDatabase->BeginTransactionL(); + lexicon = iSILexiconDB->LexiconL( aLexiconID ); + iSIDatabase->CommitChangesL( EFalse ); + + iDevASR->LoadLexicon( *lexicon ); + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::LoadModelsL +// Requests the model database handler for a model bank object to be loaded into +// the recognizer for recognition purpose. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::LoadModelsL( TSIModelBankID aModelBankID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::LoadModelsL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KLoadModels; + iModelBankID = aModelBankID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleLoadModelsL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleLoadModelsL( TSIModelBankID aModelBankID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleLoadModelsL" ); + + if ( iState == ESiPluginRecognize ) + { + + const CSIModelBank* modelBank = NULL; + // iModelBankDB keeps a reference to the modelBank object so we don't + // have to push it onto a cleanupstack. + iSIDatabase->BeginTransactionL(); + modelBank = iSIModelBankDB->AllAcousticModelsL( aModelBankID ); + iSIDatabase->CommitChangesL( EFalse ); + + iDevASR->LoadModels( *modelBank ); + + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::PlayUtteranceL +// Plays the user utterance. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::PlayUtteranceL( TSIModelBankID aModelBankID, + TSIModelID aModelID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::PlayUtteranceL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KPlayUtterance; + iModelBankID = aModelBankID; + iModelID = aModelID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RecognizeL +// Initiates recognition towards the recognizer. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RecognizeL( CSDClientResultSet& /*aClientResultSet*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RecognizeL(sd)" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RecognizeL +// Initiates recognition towards the recognizer. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RecognizeL( CSIClientResultSet& aResultSet ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::RecognizeL(si)"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRecognize ; + + iSIClientResultSet=&aResultSet; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRecognizeL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRecognizeL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRecognizeL" ); + + if ( iState == ESiPluginRecognize ) + { + iSIDatabase->BeginTransactionL(); + + if ( iSIGrammarDB->IsGrammarLoaded() ) + { + // ClientResultSet was already saved by RunL + iSIResultSet = &( iSIClientResultSet->SIResultSet() ); + iDevASR->InitRecognizerBE( *iSIResultSet ); + } + else + { + // Either the loaded grammars are empty (contains no rule) or + // all rules have been unloaded. No need to proceed any further. + iSIDatabase->CommitChangesL( ETrue ); + User::Leave( KErrNotReady ); + } + + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RecordL +// Initiates recording of user utterance. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RecordL( TTimeIntervalMicroSeconds32 aRecordTime ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RecordL" ); + + RUBY_DEBUG0( "CSIControllerPlugin::RecognizeL Returning thread priority back to normal" ); + // the priority was lowered in the StartRecSessionL as a quick fix (voice ui + // tone player had too low priority to run. Toi minimize the poorly tested + // consequences of the quick-fix, we return priority back to normal + // as soon as possible + +// Temporary fix that makes voiceui work in wk36-> sdks +// RThread().SetPriority( EPriorityNormal ); + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRecord; + iRecordTime = aRecordTime; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRecordL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRecordL( TTimeIntervalMicroSeconds32 aRecordTime ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleRecordL"); + + if ( iState == ESdPluginTrain || iState == ESiPluginRecognize ) + { + iDevASR->Record(aRecordTime); + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::PreStartSamplingL +// Pre-starts sampling before recognition start. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::PreStartSamplingL() + { + RUBY_DEBUG_BLOCK( "" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KPreStartSampling; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandlePreStartSamplingL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandlePreStartSamplingL() + { + RUBY_DEBUG_BLOCK( "" ); + iDevASR->PreStartSamplingL(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveGrammarL +// Calls the grammar database handler to remove a grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveGrammarL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRemoveGrammar; + iGrammarID = aGrammarID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveGrammarL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleRemoveGrammarL"); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->RemoveGrammarL( iClientUid, aGrammarID ); + iSIDatabase->CommitChangesL( ETrue ) ; + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveLexiconL +// Calls the lexicon database handler to remove a lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveLexiconL( TSILexiconID aLexiconID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveLexiconL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRemoveLexicon; + iLexiconID = aLexiconID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveLexiconL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveLexiconL( TSILexiconID aLexiconID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleRemoveLexiconL"); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSILexiconDB->RemoveLexiconL( iClientUid, aLexiconID ); + iSIDatabase->CommitChangesL( ETrue ) ; + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveModelBankL +// Calls the model database handler to remove a model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveModelBankL( TSIModelBankID aModelBankID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveModelBankL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRemoveModelBank; + iModelBankID = aModelBankID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveModelBankL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveModelBankL( TSIModelBankID aModelBankID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRemoveModelBankL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->RemoveModelBankL( iClientUid, aModelBankID ); + iSIDatabase->CommitChangesL( ETrue ) ; + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveModelL +// Calls the model database handler to remove a model from a model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveModelL( TSIModelBankID aModelBankID, + TSIModelID aModelID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveModelL" ); + + if ( IsActive() ) + { + + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRemoveModel; + iModelBankID = aModelBankID; + iModelID = aModelID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveModelL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveModelL( TSIModelBankID /*aModelBankID*/, + TSIModelID /*aModelID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRemoveModelL" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemovePronunciationL +// Calls the lexicon database handler to remove a pronunciation from a lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemovePronunciationL( TSILexiconID aLexiconID, + TSIPronunciationID aPronunciationID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemovePronunciationL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KRemovePronunciation; + iLexiconID = aLexiconID; + iPronunciationID = aPronunciationID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemovePronunciationL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemovePronunciationL( TSILexiconID aLexiconID, + TSIPronunciationID aPronunciationID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRemovePronunciationL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSILexiconDB->RemovePronunciationL( iClientUid, aLexiconID, aPronunciationID ); + iSIDatabase->CommitChangesL( ETrue ) ; + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveRuleL +// Calls the grammar database handler to remove a rule from a grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveRuleL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveRuleL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iState=ESiPluginRemoveRule; // handled by database modify function + iRequestFunction = KRemoveRule; + iGrammarID = aGrammarID; + iRuleID = aRuleID; + DoAsynch(); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveRuleL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveRuleL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRemoveRuleL" ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + + iSICompiledGrammarRecompile = ( CSICompiledGrammar* )iSIGrammarDB->GrammarL( aGrammarID ); + // if leave as KErrArgument + + CSIRule* aRule = &iSICompiledGrammarRecompile->AtL( iSICompiledGrammarRecompile->Find( aRuleID ) ); + + + // in a rule , all the variant have same lexicon ID, that is because + // the way it was added in addvoicetags() + CSIRuleVariant* rv = &aRule->AtL( 0 ); + TSILexiconID lexiconId = rv->LexiconID(); + + TSIPronunciationIDSequence pronunciationIdSequence; + CleanupClosePushL( pronunciationIdSequence ); + + CSILexicon* lexicon = iSILexiconDB->LexiconL( lexiconId ); + CleanupStack::PushL( lexicon ); + + for ( TInt i = 0; i < aRule->Count(); i++ ) + { + pronunciationIdSequence.Reset(); + CSIRuleVariant* rv = &aRule->AtL( i ); + rv->GetPronunciationIDsL( pronunciationIdSequence ); + for ( TInt k = 0; k < pronunciationIdSequence.Count(); k++ ) + { + lexicon->DeleteL( pronunciationIdSequence[k] ); + } + } + + // Update the lexicon + iSILexiconDB->UpdateLexiconL( iClientUid, lexicon ); + + CleanupStack::PopAndDestroy( lexicon ); + CleanupStack::PopAndDestroy( &pronunciationIdSequence ); + + + // Recompile the grammar after a deletion + // Async call, callback handled in handleeventtp + + iSICompiledGrammarRecompile->DeleteL( aRuleID ); + if ( iSICompiledGrammarRecompile->Count() == 0 ) + { + // Reset compiled data to null + iSICompiledGrammarRecompile->SetCompiledData( NULL ); + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + // Special case, do the callback now since we're not expecting + // anything from the lower layers + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRule, iResult ); + } + else + { + iDevASR->CompileGrammarL( *iSICompiledGrammarRecompile ); + } + + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RemoveRulesL +// Calls the grammar database handler to remove a set of rules from a grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RemoveRulesL( TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RemoveRulesL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iState=ESiPluginRemoveRules; // handled by database modify function + iRequestFunction = KRemoveRules; + iGrammarID = aGrammarID; + iRuleIDs = &aRuleIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleRemoveRulesL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// (other items were commented in a header). +// Note, that request to remove a non-existing rule completes successfully +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleRemoveRulesL( TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleRemoveRulesL" ); + TInt i( 0 ); + + RUBY_DEBUG1( "CSIControllerPlugin::HandleRemoveRulesL grammarId [%d]", aGrammarID ); + RUBY_DEBUG1( "CSIControllerPlugin::HandleRemoveRulesL aRuleIDs.Count() = [%d]", aRuleIDs.Count() ); + + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + + // 1.Get the lexion id + // 2. For each rule, delete it's varant's prounication from lexicon and then delete the rule from grammar + // 3. Update lexicon DB. + // 4. Recompile the grammar + // Get the grammar ,use all rules, so it clean up when iSIGrammarDB is deleted + RUBY_DEBUG1( "CSIControllerPlugin::HandleRemoveRulesL Getting All rules for grammarID [%d]", aGrammarID ); + + iSICompiledGrammarRecompile = ( CSICompiledGrammar* )iSIGrammarDB->GrammarL( aGrammarID ); + __UHEAP_MARK; + RPointerArray aLexiconArray; + CleanupClosePushL( aLexiconArray ); + RArray aLexiconIDs; + CleanupClosePushL( aLexiconIDs ); + CSILexicon* aLexicon; + + // if leave as KErrArgument + for ( i = 0; i < aRuleIDs.Count(); i++ ) + { + TSIRuleID aRuleID = aRuleIDs[i]; + TInt removeRuleIndex = iSICompiledGrammarRecompile->Find( aRuleID ); + CSIRule* aRule = NULL; // rule to remove + if ( removeRuleIndex == KErrNotFound ) + { + RUBY_DEBUG1("CSIControllerPlugin::HandleRemoveRulesL RuleID [%d] not found. Probably already deleted", aRuleID ); + // Nothing to delete in this round. + // Proceed to the next one + continue; + } + else if ( removeRuleIndex >= 0 ) + { + aRule = &iSICompiledGrammarRecompile->AtL( removeRuleIndex ); + } + else + { + // Unknown error + User::Leave( removeRuleIndex ); + } + // in a rule , all the variant have same lexicon ID, + // and all the rule's rule variant have same lexicon ID, + // one lexicon corresponding to one grammar + // that is because the way it was added in addvoicetags() + CSIRuleVariant* aRv = &aRule->AtL( 0 ); + TSILexiconID aLexiconID = aRv->LexiconID(); + + // This hack ensures 4 byte alignment in winscw + TSILexiconID* lexID = new ( ELeave ) TSILexiconID; + CleanupStack::PushL( lexID ); + *lexID = aRv->LexiconID(); + // Uniq ids array + aLexiconIDs.InsertInSignedKeyOrder( *lexID ); + CleanupStack::PopAndDestroy( lexID ); + } + // collect the lexicon according to the uniq lexicon array + for ( i = 0; i < aLexiconIDs.Count(); i++ ) + { + aLexicon = iSILexiconDB->LexiconL( aLexiconIDs[i] ); + aLexiconArray.Append( aLexicon ); + } + + for ( i = 0; i < aRuleIDs.Count(); i++ ) + { + TSIRuleID aRuleID = aRuleIDs[i]; + + TInt removeRuleIndex = iSICompiledGrammarRecompile->Find( aRuleID ); + CSIRule* aRule = NULL; // rule to remove + if ( removeRuleIndex == KErrNotFound ) + { + RUBY_DEBUG1("CSIControllerPlugin::HandleRemoveRulesL RuleID [%d] not found. Probably already deleted", aRuleID ); + // Nothing to delete in this round. + // Proceed to the next one + continue; + } + else if ( removeRuleIndex >= 0 ) + { + aRule = &iSICompiledGrammarRecompile->AtL( removeRuleIndex ); + } + else + { + // Unknown error + User::Leave( removeRuleIndex ); + } + + // in a rule , all the variant have same lexicon ID, that is because + // the way it was added in addvoicetags() + + TSIPronunciationIDSequence aIPronunciationIDSequence; + CleanupClosePushL( aIPronunciationIDSequence ); + + for ( TInt i = 0 ; i < aRule->Count() ; i++ ) + { + aIPronunciationIDSequence.Reset(); + CSIRuleVariant* aRv = &aRule->AtL( i ); + aRv->GetPronunciationIDsL( aIPronunciationIDSequence ); + TSILexiconID aLexiconID = aRv->LexiconID(); + TInt aLocation = 0; + for ( TInt s = 0 ; s < aLexiconIDs.Count() ; s++ ) + { + if ( aLexiconIDs[s] == aLexiconID ) + { + aLocation = s; + break; + } + } + + CSILexicon* aLexicon =aLexiconArray[aLocation]; + for ( TInt k = 0 ; k < aIPronunciationIDSequence.Count() ; k++ ) + { + aLexicon->DeleteL( aIPronunciationIDSequence[k] ); + } + } + + // delete aIPronunciationIDSequence + CleanupStack::PopAndDestroy( &aIPronunciationIDSequence ); + + // Recompile the grammar after a deletion + // Async call, callback handled in handleeventtp + //delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile->DeleteL( aRuleID ); + } + + // Update the lexicon + for ( i = 0; i < aLexiconArray.Count(); i++ ) + { + iSILexiconDB->UpdateLexiconL( iClientUid, aLexiconArray[i] ); + } + + // clean up + // Close the arrays + //aLexiconIDs.Close(); + CleanupStack::PopAndDestroy( &aLexiconIDs ); // CleanupClosePushL aLexiconIDs + aLexiconArray.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &aLexiconArray ); //aLexiconArray + __UHEAP_MARKEND; + + if ( iSICompiledGrammarRecompile->Count() == 0 ) + { + // Reset compiled data to null + iSICompiledGrammarRecompile->SetCompiledData( NULL ); + + iSIDatabase->BeginTransactionL(); + // save the compiled grammar + TRAPD( error, iSIGrammarDB->UpdateGrammarL( iClientUid,iSICompiledGrammarRecompile ) ); + iSIDatabase->CommitChangesL( ETrue ); + if ( error ) + { + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRules, error ); + delete iSICompiledGrammarRecompile; + iState = ESiPluginIdle; + return; + } + TRAP( error, iSIDatabase->CommitChangesL( ETrue ) ); + + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + iState = ESiPluginIdle; + + // Special case, do the callback now since we're not expecting + // anything from the lower layers + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRules, error ); + } // if ( iSICompiledGrammarRecompile->Count() == 0 ) + else + { + iDevASR->CompileGrammarL( *iSICompiledGrammarRecompile ); + } + + } // if ( iClientRegistered ) + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::SetClientUid +// Sets the client's UID for data ownership identification. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::SetClientUid( TUid aClientUid ) + { + RUBY_DEBUG0( "CSIControllerPlugin::SetClientUid") ; + iClientUid = aClientUid; + iClientRegistered = ETrue; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::SetPrioritySettings +// Set the priority settings for this controller. This is used during recording +// and playback. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::SetPrioritySettings( const TMMFPrioritySettings& aPrioritySettings ) + { + RUBY_DEBUG0( "CSIControllerPlugin::SetPrioritySettings" ); + iDevASR->SetPrioritySettings( aPrioritySettings ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::StartRecSessionL +// Initiates a recognition session. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::StartRecSessionL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::StartRecSessionL" ); + RThread().SetPriority( EPriorityAbsoluteLow ); + RUBY_DEBUG0( "CSIControllerPlugin::StartRecSessionL Lowered thread priority to absolute low" ); + //RUBY_DEBUG1( "CSIControllerPlugin::StartRecSessionL Thread id is [%x]", RThread().Id() ); + + if ( iState == ESiPluginIdle ) + { + + User::LeaveIfError( iDevASR->StartRecSession( ESiRecognition ) ); + iState = ESiPluginRecognize; + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::TrainL +// Initiates a speaker depedent training session. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::TrainL( TSIModelBankID aModelBankID, + TSIModelID& aModelID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::TrainL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KTrain; + iModelBankID = aModelBankID; + iModelIDPtr = &aModelID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleTrainL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleTrainL( TSIModelBankID /*aModelBankID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleTrainL" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::UnloadRuleL +// Unloads a rule from the recognizer for this recognition session. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::UnloadRuleL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::UnloadRuleL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KUnloadRule; + iGrammarID = aGrammarID; + iRuleID = aRuleID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleUnloadRuleL +// This is the asynchronous handle called from the CSIAsyncHandler object. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleUnloadRuleL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleUnloadRuleL" ); + iDevASR->UnloadRule( aGrammarID, aRuleID ); // for blacklisting only + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleUnloadRuleL +// Notification from DevASR when feature vectors are available. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::FeatureVectorDataRcvd( const TDesC8& /*aFV*/, + TInt32 /*aSNR*/, + TInt32 /*aPosition*/ ) + { + RUBY_DEBUG0( "CSIControllerPlugin::FeatureVectorDataRcvd" ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::DevASREvent +// Event from DevASR interface. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::DevASREvent( TDevASREvent aEvent, + TDevASRError aError ) + { + RUBY_DEBUG2( "CSIControllerPlugin::DevASREvent (Event=%d, Error=%d)", aEvent, aError ); + + switch ( iState ) + { + case ESdPluginTrain: + TRAP_IGNORE( HandleEventTrainL( aEvent, aError ) ); + break; + case ESiPluginRecognize: + HandleEventRecognize( aEvent, aError ); + break; + case ESiPluginPlay: + TRAP_IGNORE( HandleEventPlayL( aEvent, aError ) ); + break; + case ESiPluginTrainText: + HandleEventTTP( aEvent, aError ); + break; +#ifdef __SINDE_TRAINING + case ESiPluginTrainSinde: + iSindeTrainer->HandleEvent( aEvent, aError ); + break; +#endif // __SINDE_TRAINING + case ESiPluginRemoveRule: + HandleEventRemoveRule( aEvent, aError ); + break; + case ESiPluginRemoveRules: + RUBY_DEBUG0( "CSIControllerPlugin::DevASREvent case iState ESiPluginRemoveRules" ); + HandleEventRemoveRules( aEvent, aError ); + break; + case ESiPluginIdle: + break; + default: + // Unexpected or cancelled message + break; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RequestSpeechData +// Get speech data from audio buffer +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RequestSpeechData() + { + const TInt KBufferMaxLength( 4000 ); + TInt sizeLeft( iAudioBuffer->Size() - iNSamplesSent * 2 ); + if ( sizeLeft == 0 ) + { + // nothing + } + else if ( sizeLeft < KBufferMaxLength*2 ) + { + // last buffer + iCurrentAudioBuffer.Set( iAudioBuffer->Right( sizeLeft ) ); + iDevASR->SendSpeechData( iCurrentAudioBuffer, ETrue ); + + iNSamplesSent += sizeLeft/2; + } + else + { + iCurrentAudioBuffer.Set( iAudioBuffer->Mid( 2*iNSamplesSent, 2*KBufferMaxLength ) ); + + iDevASR->SendSpeechData( iCurrentAudioBuffer, EFalse ); + iNSamplesSent += KBufferMaxLength; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::SILexiconL +// Load lexicon by this call back functionDevAsr Take the owner ship of the lexicon +// ----------------------------------------------------------------------------- +// +CSILexicon* CSIControllerPlugin::SILexiconL( TSILexiconID anID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::SILexiconL"); + + iSIDatabase->BeginTransactionL(); + CSILexicon* lexicon = iSILexiconDB->LexiconL(anID); + iSIDatabase->CommitChangesL( EFalse ); + + return lexicon; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::ConfigurationData +// DevASR calls this method to get configuration data. +// ----------------------------------------------------------------------------- +// +HBufC8* CSIControllerPlugin::ConfigurationData( TUint32 aPackageType, + TUint32 aPackageID, + TUint32 aStartPosition , + TUint32 aEndPosition ) + { + RUBY_DEBUG0( "ConfigurationData::MdtoConfigurationData" ); + return ( iDataLoader->LoadData( aPackageType, aPackageID, + aStartPosition, aEndPosition ) ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::DevASRMessage +// A message in response to a custom command. This controller never sends a +// custom command. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::DevASRMessage( TDesC8& /*aMsg*/ ) + { + // SI Controller Plugin does not implement this event. + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::PlayL +// Plays the trained user utterance. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::PlayL( TSIModelBankID /*aModelBankID*/, + TSIModelID /*aModelID*/ ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::PlayL"); + User::Leave(KErrNotSupported); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventPlayL +// Handling of DevASR event in Play state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventPlayL( TDevASREvent/* aEvent*/, + TDevASRError/* aError*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleEventPlayL" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventPlayL +// Handling of DevASR event in RemoveRule state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventRemoveRule( TDevASREvent aEvent, + TDevASRError aError ) + { + iState = ESiPluginIdle; + + if ( aError ) + { + iControllerIf.SendSrsEvent(KUidAsrEventRemoveRule, aError); + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + return; + } + + switch (aEvent) + { + case EDevASRGrammarCompile: + { + TRAPD( error, + iSIDatabase->BeginTransactionL(); + // save the compiled grammar + iSIGrammarDB->UpdateGrammarL( iClientUid, iSICompiledGrammarRecompile ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAPD + if ( error ) + { + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRule, error ); + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + iState = ESiPluginIdle; + return; + } + TRAP( error, iSIDatabase->CommitChangesL( ETrue ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRule, error ); + + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + iState = ESiPluginIdle; + break; + + } + default: + // Unexpected or cancelled message + RUBY_DEBUG0( "CSIControllerPlugin::HandleEventRemoveRule. Unexpected.") ; + break; + } + + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventRemoveRules +// Handling of DevASR event in RemoveRules state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventRemoveRules( TDevASREvent aEvent, + TDevASRError aError ) + { + RUBY_DEBUG2( "CSIControllerPlugin::HandleEventRemoveRules. Event [%d], Error [%d]", aEvent, aError ); + + iState = ESiPluginIdle; + + if ( aError ) + { + iControllerIf.SendSrsEvent(KUidAsrEventRemoveRules, aError); + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + return; + } + + switch ( aEvent ) + { + case EDevASRGrammarCompile: + { + TRAPD( error, + iSIDatabase->BeginTransactionL(); + // save the compiled grammar + iSIGrammarDB->UpdateGrammarL( iClientUid, iSICompiledGrammarRecompile ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAPD + + if ( error ) + { + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRules, error ); + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + iState = ESiPluginIdle; + return; + } + TRAP( error, iSIDatabase->CommitChangesL( ETrue ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRules, error ); + + delete iSICompiledGrammarRecompile; + iSICompiledGrammarRecompile = NULL; + iState = ESiPluginIdle; + break; + + } + default: + // Unexpected or cancelled message + RUBY_DEBUG0( "CSIControllerPlugin::HandleEventRemoveRules. Unexpected." ); + break; + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventTTP +// Handling of DevASR event in TTP state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventTTP( TDevASREvent aEvent, + TDevASRError aError ) + { + if ( aError ) + { + iControllerIf.SendSrsEvent(KUidAsrEventAddVoiceTags, aError); + iState = ESiPluginIdle; + return; + } + + switch ( aEvent ) + { + case EDevASRTrainFromText: + //case EDevASRTrainFromTextFinished: + { + + TRAPD( error, + UpdateGrammarAndLexiconDBL( iSITtpWordList, iLexiconID, iGrammarID,*iRuleIDs ); + iSIDatabase->BeginTransactionL(); + iSICompiledGrammar = ( CSICompiledGrammar* )iSIGrammarDB->LoadGrammarL( iGrammarID ); + iSIDatabase->CommitChangesL( EFalse ); + iDevASR->CompileGrammarL( *iSICompiledGrammar ); + ); + if ( error ) + { + iControllerIf.SendSrsEvent( KUidAsrEventAddVoiceTags, error ); + iState = ESiPluginIdle; + return; + } + + break; + } + case EDevASRGrammarCompile: + { + TInt error = KErrNone; + TRAP( error, + iSIDatabase->BeginTransactionL(); + // save the compiled grammar + iSIGrammarDB->UpdateGrammarL( iClientUid, iSICompiledGrammar ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAP + iControllerIf.SendSrsEvent( KUidAsrEventAddVoiceTags, error ); + iState = ESiPluginIdle; + break; + } + default: + // Unexpected or cancelled message + RUBY_DEBUG0( "CSIControllerPlugin::HandleEventTTP. Unexpected." ); + break; + + } + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventRecognizeL +// Handling of DevASR event in Recognition state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventRecognize( TDevASREvent aEvent, + TDevASRError aError ) + { + RUBY_DEBUG2( "CSIControllerPlugin::HandleEventRecognize - Event=%d, Error=%d", aEvent, aError); + + switch ( aEvent ) + { + case EDevASRLoadModels: + // case EDevASRModelsLoaded: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRLoadModels failed with error [%d]", aError ); + + TRAP_IGNORE( + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->ResetAndDestroy(); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAP_IGNORE + + iState = ESiPluginIdle; + } + + iControllerIf.SendSrsEvent( KUidAsrEventLoadModels, aError ); + break; + case EDevASRLoadLexicon: + // case EDevASRLexiconLoaded: + + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRLoadLexicon failed with error [%d]", aError ); + iSIModelBankDB->ResetAndDestroy(); + iSILexiconDB->ResetAndDestroy(); + iState = ESiPluginIdle; + } + iControllerIf.SendSrsEvent( KUidAsrEventLoadLexicon, aError ); + break; + + case EDevASRLoadGrammar: + // case EDevASRGrammarLoaded: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRLoadGrammar failed with error [%d]", aError ); + + iSIModelBankDB->ResetAndDestroy(); + iSILexiconDB->ResetAndDestroy(); + iSIGrammarDB->ResetAndDestroy(); + iState = ESiPluginIdle; + } + iControllerIf.SendSrsEvent( KUidAsrEventLoadGrammar, aError ); + break; + + case EDevASRInitRecognitionBackend: + //case EDevASRRecBEInitialized: + if ( aError == KErrNone ) + { + iDevASR->InitFrontEnd( ESiRecognition ); + } + else + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRInitRecognitionBackend failed with error [%d]", aError ); + + RecognitionReset(); + iControllerIf.SendSrsEvent( KUidAsrEventRecognition, KErrAsrInitializationFailure ); + } + break; + + case EDevASRInitFrontend: + //case EDevASRFEInitialized: + + if ( aError == KErrNone ) + { + iControllerIf.SendSrsEvent( KUidAsrEventRecognitionReady, KErrNone ); + } + else + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRInitFrontend failed with error [%d]", aError ); + + RecognitionReset(); + iControllerIf.SendSrsEvent( KUidAsrEventRecognition, KErrAsrInitializationFailure ); + } + break; + + case EDevASRRecordStarted: + //case EDevASRRecordStarted: + + iControllerIf.SendSrsEvent( KUidAsrEventRecordStarted, aError ); + break; + + case EDevASRRecord: + //case EDevASRRecordFinished: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRRecord failed with error [%d]", aError ); + + RecognitionReset(); + } + iControllerIf.SendSrsEvent( KUidAsrEventRecord, aError ); + break; + + case EDevASRAdapt: // adaptation finished + // case EDevASRAdaptFinished: // adaptation finished + + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRAdapt failed with error [%d]", aError ); + + iControllerIf.SendSrsEvent( KUidAsrEventAdapt, aError ); + } + else + { + // save the models , iModelBankID decided in loadmodel() + TRAPD( error, + iSIDatabase->BeginTransactionL(); + iSIModelBankDB->SaveModelL( iModelBankID ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAPD + iControllerIf.SendSrsEvent( KUidAsrEventAdapt, error ); + } + break; + case EDevASREouDetected: + //case EDevASRRecordFinished: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASREouDetected failed with error [%d]", aError ); + + RecognitionReset(); + } + iControllerIf.SendSrsEvent( KUidAsrEventEouDetected, aError ); + break; + + // case EDevASREouDetected: + + case EDevASRRecognize: + + { + if ( aError == KErrNone ) + { + + // Copy result into client result + if ( ProcessRecognitionComplete() > 0 ) + { + iResult = KErrNone; + } + else + { + iResult = KErrAsrNoMatch; + } + } + else if (aError ==KErrOverflow ||aError ==KErrArgument ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRRecognize failed with error [%d]", aError ); + + iResult = aError; + } + else + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRRecognize failed with error [%d]", aError ); + + if ( aError != KErrAsrNoSpeech && + aError != KErrAsrSpeechTooEarly && + aError != KErrAsrSpeechTooLong && + aError != KErrAsrSpeechTooShort && + aError != KErrTimedOut && + aError !=KErrOverflow && + aError !=KErrArgument + ) + { + RecognitionReset(); + } + iResult = aError; + } + + iControllerIf.SendSrsEvent(KUidAsrEventRecognition, iResult); + + // iControllerIf.SendSrsEvent(KUidAsrEventRecognition, iResult); + break; + } + case EDevASRPlayStarted: + iControllerIf.SendSrsEvent(KUidAsrEventPlayStarted, aError); + break; + + case EDevASRPlay: + //case EDevASRPlayFinished: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRPlay failed with error [%d]", aError ); + + RecognitionReset(); + } + iControllerIf.SendSrsEvent(KUidAsrEventPlay, aError); + break; + case EDevASRActivateGrammar: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRActivateGrammar failed with error [%d]", aError ); + + RecognitionReset(); + } + iControllerIf.SendSrsEvent(KUidAsrEventActivateGrammar, aError); + break; + case EDevASRDeactivateGrammar: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRDeactivateGrammar failed with error [%d]", aError ); + + RecognitionReset(); + } + iControllerIf.SendSrsEvent(KUidAsrEventDeactivateGrammar, aError); + break; + case EDevASRUnloadGrammar: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRUnloadGrammar failed with error [%d]", aError ); + + RecognitionReset(); + } + else + { + TRAP_IGNORE( + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->UnloadGrammarL( iGrammarID ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAP_IGNORE + } + + iControllerIf.SendSrsEvent(KUidAsrEventUnloadGrammar, aError); + break; + case EDevASRUnloadRule: + if ( aError != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::HandleEventRecognize. EDevASRUnloadRule failed with error [%d]", aError ); + + //RecognitionReset(); + } + else + { + TRAP_IGNORE( + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->UnloadRuleL( iGrammarID, iRuleID ); + iSIDatabase->CommitChangesL( ETrue ); + ); // TRAPD + } + iControllerIf.SendSrsEvent( KUidAsrEventUnloadRule, aError ); + break; + + default: + // Unexpected or cancelled message + RUBY_DEBUG0( "CSIControllerPlugin::HandleEventRecognize. Unexpected." ); + + break; + } + +} + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEventTrainL +// Handling of DevASR event in Train state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEventTrainL( TDevASREvent /*aEvent*/, + TDevASRError /*aError*/ ) +{ + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleEventTrainL" ); + User::Leave( KErrNotSupported ); +} + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateNewRuleL +// Create a empty rule into a given grammar +// ----------------------------------------------------------------------------- +// +CSIRule* CSIControllerPlugin::CreateNewRuleL( CSICompiledGrammar* aGrammar ) + { + RUBY_DEBUG_BLOCKL("CSIControllerPlugin::CreateNewRuleL"); + TInt aID=0; + TInt Count=aGrammar->Count(); + // existing myRuleVariantID + RArray myIDs; + myIDs.Reset(); + for( TInt i = 0; i < Count; i++ ) + { + CSIRule* aRule=&(aGrammar->AtL(i)); + myIDs.Append(aRule->RuleID()); + } + // Find a uniq new id + iSIDatabase->BeginTransactionL(); + aID=iSIGrammarDB->GetNewID(myIDs); + iSIDatabase->CommitChangesL( EFalse ); + + myIDs.Close(); + CSIRule* aRule = CSIRule::NewL(aID); + return( aRule ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddNewRuleVariantL +// Create new rule variant within a rule +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddNewRuleVariantL( CSIRule& aRule, + TSILexiconID aLexiconID, + RArray& aPronunciationIDs, + CSIParameters& aParameters ) + { + RUBY_DEBUG_BLOCKL( "CSIControllerPlugin::AddNewRuleVariantL" ); + // existing myRuleVariantID + RArray myID; + myID.Reset(); + TInt i( 0 ); + for( i = 0; i < aRule.Count(); i++ ) { + CSIRuleVariant* aRuleVariant=&(aRule.AtL(i)); + myID.Append(aRuleVariant->RuleVariantID()); + } + + iSIDatabase->BeginTransactionL(); + + // Find a uniq new id + TSIRuleVariantID aRuleVariantID=STATIC_CAST(TSIRuleVariantID,iSIGrammarDB->GetNewID(myID)); + myID.Close(); + + iSIDatabase->CommitChangesL( ETrue ); + + // add the rule variant to the rule + CSIRuleVariant* ruleVariant= CSIRuleVariant::NewL(aRuleVariantID,aLexiconID); + CleanupStack::PushL( ruleVariant ); + ruleVariant->SetPronunciationIDsL( aPronunciationIDs ); + RArray parameterIDs; + CleanupClosePushL( parameterIDs ); + RArray parameterValues; + CleanupClosePushL( parameterValues ); + + // copy parameters + aParameters.ListParametersL( parameterIDs, parameterValues ); + + if ( parameterIDs.Count() != parameterValues.Count() ) + { + User::Leave( KErrCorrupt ); + } + for ( i = 0; i < parameterIDs.Count(); i++ ) + { + ruleVariant->SetParameterL( parameterIDs[i], parameterValues[i] ); + } + + CleanupStack::PopAndDestroy(); // parameterValues + CleanupStack::PopAndDestroy(); // parameterIDs + aRule.AddL( ruleVariant ); + CleanupStack::Pop( ruleVariant ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateNewPronunciationL +// Create a empty pronunciation into a given lexicon +// ----------------------------------------------------------------------------- +// +TSIPronunciationID CSIControllerPlugin::CreateNewPronunciationL( CSILexicon* aLexicon, + TDesC8& aPronunciationPr, + TSIModelBankID aModelBankID) + { + RUBY_DEBUG_BLOCKL( "CSIControllerPlugin::CreateNewPronunciationL" ); + + TSIPronunciationID pronunciationID( 0 ); + + if ( aLexicon->Count() ) + { + pronunciationID = aLexicon->AtL( aLexicon->Count() - 1 ).PronunciationID() + 1; + } + + // RUBY_DEBUG1("pronunID = %i", pronunciationID ); + // add the Pronunciation to the Pronunciation + CSIPronunciation* pronunciation = CSIPronunciation::NewL( pronunciationID, aModelBankID ); + + CleanupStack::PushL( pronunciation ); + pronunciation->SetPhonemeSequenceL( aPronunciationPr ); + TRAPD( error, aLexicon->AddL( pronunciation ) ); + if ( error == KErrAlreadyExists ) + { +#ifdef __SIND_LEXICON_OPT + // Take the existing pronunciation ID + TInt index = aLexicon->Find( aPronunciationPr ); + pronunciationID = aLexicon->AtL( index ).PronunciationID(); + + CleanupStack::PopAndDestroy( pronunciation ); +#else + // try to find non-existing id in the middle of range + RUBY_DEBUG0( "pronunID already exists" ); + RArray myPronunciationID; + myPronunciationID.Reset(); + for ( TInt i = 0; i < aLexicon->Count(); i++ ) + { + CSIPronunciation* tmpPronunciation=&( aLexicon->AtL( i ) ); + myPronunciationID.Append( tmpPronunciation->PronunciationID() ); + } + + // Find a uniq new id + iSIDatabase->BeginTransactionL(); + pronunciationID = iSILexiconDB->GetNewID( myPronunciationID ); + iSIDatabase->CommitChangesL( ETrue ); + + pronunciation->SetPronunciationID( pronunciationID ); + + myPronunciationID.Close(); + aLexicon->AddL( pronunciation ); +#endif // __SIND_LEXICON_OPT + } + else + { + User::LeaveIfError( error ); +#ifdef __SIND_LEXICON_OPT + CleanupStack::Pop( pronunciation ); +#endif // __SIND_LEXICON_OPT + } + +#ifndef __SIND_LEXICON_OPT + CleanupStack::Pop( pronunciation ); +#endif // __SIND_LEXICON_OPT + + RUBY_DEBUG1( "CSIControllerPlugin::CreateNewPronunciationL pronunciationID=%x", pronunciationID ); + return pronunciationID; + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::UpdateGrammarAndLexiconDBL +// Save TTP result into the given grammar and lexicon of the plugin database +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::UpdateGrammarAndLexiconDBL( CSITtpWordList* aSITtpWordList, + TSILexiconID aLexiconID, + TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::UpdateGrammarAndLexiconDBL" ); + CleanupClosePushL( aRuleIDs ); + + iSITtpWordList = aSITtpWordList; + iLexiconID = aLexiconID; + iGrammarID = aGrammarID; + iRuleIDs = &aRuleIDs; + + aRuleIDs.Reset(); + + iSIDatabase->BeginTransactionL(); + + // is grammar already in database? + iSIGrammarDB->VerifyOwnershipL( iClientUid, KGrammarIdTable, KGrammarIndex, iGrammarID ); + CSICompiledGrammar* aGrammar = (CSICompiledGrammar* )iSIGrammarDB->GrammarL( iGrammarID ); + CleanupStack::PushL( aGrammar ); + + //is lexicion already in database? + iSILexiconDB->VerifyOwnershipL( iClientUid, KLexiconIdTable, KLexiconIndex, iLexiconID ); + CSILexicon* aLexicon = iSILexiconDB->LexiconL( iLexiconID ); + CleanupStack::PushL( aLexicon ); + + iSIDatabase->CommitChangesL( EFalse ); + + + // unpack the iSITtpWordList; + for ( TInt i = 0; i < iSITtpWordList->Count(); i++ ) + { + //iSIDatabase->BeginTransactionL(); + // Get pronunciations + RPointerArray pronunciations; + RArray pronunciationIDs; + CleanupClosePushL( pronunciationIDs ); + CleanupClosePushL( pronunciations ); + iSITtpWordList->GetPronunciationsL( i, pronunciations ); + + RUBY_DEBUG1( "CSIControllerPlugin::UpdateGrammarAndLexiconDBL pronunciations.Count=%d", pronunciations.Count() ); + + // if pronunciation generation failed, skip that word. + if ( pronunciations.Count() == 0 ) + { + CleanupStack::PopAndDestroy( &pronunciations ); + CleanupStack::PopAndDestroy( &pronunciationIDs ); + User::LeaveIfError( aRuleIDs.Append( KInvalidRuleID ) ); + continue; + } + + // Create a empty rule into grammar, one name -> one rule; + TSIRuleID ruleID; + + + CSIRule* rule=CreateNewRuleL(aGrammar); + CleanupStack::PushL( rule ); + ruleID=rule->RuleID(); + User::LeaveIfError( aRuleIDs.Append( ruleID ) ); + + for(TInt k=0;kCount(); n++ ) + { + // Add Prounication into lexicon + + TSIPronunciationID aPronunciationID = CreateNewPronunciationL( aLexicon,pronunciations[k]->PronunciationL( n ), + iModelBankID ); + User::LeaveIfError( pronunciationIDs.Append( aPronunciationID ) ); + } + + // Add RuleVariant into grammar + AddNewRuleVariantL(*rule, aLexiconID, pronunciationIDs, *pronunciations[k] ); + } + + + aGrammar->AddL( rule ); + CleanupStack::Pop( rule ); + + // Close the arrays + CleanupStack::PopAndDestroy( &pronunciations ); + CleanupStack::PopAndDestroy( &pronunciationIDs ); + } + + RUBY_DEBUG0( "CSIControllerPlugin::UpdateGrammarAndLexiconDBL" ); + + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->UpdateGrammarL( iClientUid,aGrammar ); + iSILexiconDB->UpdateLexiconL( iClientUid,aLexicon ); + iSIDatabase->CommitChangesL( ETrue ); + CleanupStack::PopAndDestroy( 2 ); // aGrammar aLexicon + + CleanupStack::Pop(); //aRuleIDs + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RecognitionReset +// Terminate recognition session. Free up resources and return to IDLE state. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RecognitionReset() + { + iSIModelBankDB->ResetAndDestroy(); + iSILexiconDB->ResetAndDestroy(); // Grcompiler takes the ownership of it + iSIGrammarDB->ResetAndDestroy(); + iState = ESiPluginIdle; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::ProcessTrainCompleteL +// Training is complete. Store the acoustic model and user utterance into the +// model bank. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::ProcessTrainCompleteL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::ProcessTrainCompleteL" ); + // No need to train it at all + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::ProcessRecognitionCompleteL +// Recogntion is complete. Transfer the result from the recognizer into the result +// object sent by the client. +// ----------------------------------------------------------------------------- +// +TInt CSIControllerPlugin::ProcessRecognitionComplete() + { + RUBY_DEBUG0( "CSIControllerPlugin::ProcessRecognitionComplete" ); + + const CSIResult* result = 0; + CSIClientResult* clientResult = 0; + + TInt resultsAvailable = iSIResultSet->Count(); + TInt resultsWanted = iSIClientResultSet->MaxResults(); + TInt count = Min( resultsAvailable, resultsWanted ); + + // Copy the results from the recognizer into client's result set object + TInt resCount = 0; + + + for ( TInt i = 0; i < count; i++ ) + { + TRAPD( err, result = &( iSIResultSet->AtL( i ) ) ); + if ( err ) + { + return 0; + } + RUBY_DEBUG2( "CSIControllerPlugin::ProcessRecognitionComplete rank(%d): grammarId(%d)", i+1, result->GrammarID() ); + RUBY_DEBUG2( "CSIControllerPlugin::ProcessRecognitionComplete ruleId(%d), score(%d)", result->RuleID(), result->Score() ); + + if ( result->Score() > 0 ) + { + TRAP( err, clientResult = CSIClientResult::NewL( result->GrammarID(), + result->RuleID() ) ); + if ( err ) + { + return 0; + } + TRAP( err, iSIClientResultSet->AddL( clientResult ) ); + if ( err ) + { + return 0; + } + resCount++; + } + else + { + break; + } + } + + iSIClientResultSet->SetResultCount( resCount ); + return resCount; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::DoCancel +// Cancel handle from CActive class. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::DoCancel() + { + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::RunL +// RunL from CActive class. Check which message got saved and call the +// appropriate handle function. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::RunL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::RunL" ); + switch ( iRequestFunction ) + { + case KAddRule: + TRAP( iResult, HandleAddRuleL( iGrammarID, iLexiconID, iPronunciationID, *iRuleIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventAddRule, iResult ); + break; + + case KCreateGrammar: + TRAP( iResult, HandleCreateGrammarL( *iGrammarIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventCreateGrammar, iResult ); + break; + + case KCreateLexicon: + TRAP( iResult, HandleCreateLexiconL( *iLexiconIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventCreateLexicon, iResult ); + break; + + case KCreateModelBank: + TRAP( iResult, HandleCreateModelBankL( *iModelBankIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventCreateModelBank, iResult ); + break; + + case KGetAllClientGrammarIDs: + TRAP( iResult, HandleGetAllClientGrammarIDsL( *iGrammarIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllClientGrammarIDs, iResult ); + break; + + case KGetAllClientLexiconIDs: + TRAP( iResult, HandleGetAllClientLexiconIDsL( *iLexiconIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllClientLexiconIDs, iResult ); + break; + + case KGetAllClientModelBankIDs: + TRAP( iResult, HandleGetAllClientModelBankIDsL( *iModelBankIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllClientModelBankIDs, iResult ); + break; + + case KGetAllGrammarIDs: + TRAP( iResult, HandleGetAllGrammarIDsL( *iGrammarIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllGrammarIDs, iResult ); + break; + + case KGetAllLexiconIDs: + TRAP( iResult, HandleGetAllLexiconIDsL( *iLexiconIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllLexiconIDs, iResult ); + break; + + case KGetAllModelBankIDs: + TRAP( iResult, HandleGetAllModelBankIDsL( *iModelBankIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllModelBankIDs, iResult ); + break; + + case KGetAllModelIDs: + TRAP( iResult, HandleGetAllModelIDsL( iModelBankID, *iModelIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllModelIDs, iResult ); + break; + + case KGetAllPronunciationIDs: + TRAP( iResult, HandleGetAllPronunciationIDsL( iLexiconID, *iPronunciationIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllPronunciationIDs, iResult ); + break; + + case KGetAllRuleIDs: + TRAP( iResult, HandleGetAllRuleIDsL( iGrammarID, *iRuleIDs ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAllRuleIDs, iResult ); + break; + + case KGetAvailableStorage: + TRAP( iResult, HandleGetAvailableStorageL( *iCountPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetAvailableStorage, iResult ); + break; + + case KGetModelCount: + TRAP( iResult, HandleGetModelCountL( iModelBankID, *iCountPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetModelCount, iResult ); + break; + + case KGetPronunciationCount: + TRAP( iResult, HandleGetPronunciationCountL( iLexiconID, *iCountPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetPronunciationCount, iResult ); + break; + + case KGetRuleCount: + TRAP( iResult, HandleGetRuleCountL( iGrammarID, *iCountPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetRuleCount, iResult ); + break; + case KGetRuleValidity: + TRAP( iResult, HandleGetRuleValidityL( iGrammarID, iRuleID, *iValidPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetRuleValidity, iResult ); + break; + + case KGetUtteranceDuration: + TRAP( iResult, HandleGetUtteranceDurationL( iModelBankID, iModelID, *iDurationPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventGetUtteranceDuration, iResult ); + break; + + case KLoadGrammar: + TRAP( iResult, HandleLoadGrammarL( iGrammarID ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KLoadGrammar. HandleLoadGrammarL Left with error [%d]", iResult ); + // iGrammarDB needs to be reset also since multiple grammars can + // be loaded and this may not be the first grammar. + iSIModelBankDB->ResetAndDestroy(); + iSILexiconDB->ResetAndDestroy(); + iSIGrammarDB->ResetAndDestroy(); + iState = ESiPluginIdle; + iControllerIf.SendSrsEvent( KUidAsrEventLoadGrammar, iResult ); + } + break; + + case KLoadLexicon: + TRAP(iResult, HandleLoadLexiconL( iLexiconID ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KLoadLexicon. HandleLoadGrammarL Left with error [%d]", iResult ); + + // iLexiconDB needs to be reset also since multiple lexicons can + // be loaded and this may not be the first lexicon. + iSIModelBankDB->ResetAndDestroy(); + iSILexiconDB->ResetAndDestroy(); + iState = ESiPluginIdle; + iControllerIf.SendSrsEvent( KUidAsrEventLoadLexicon, iResult ); + } + break; + + case KLoadModels: + TRAP(iResult, HandleLoadModelsL( iModelBankID ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KLoadModels. HandleLoadGrammarL Left with error [%d]", iResult ); + + if ( iResult == KErrCorrupt ) + { + RUBY_DEBUG0( "CSIControllerPlugin::RunL. KLoadModels. Try to update models" ); + TRAP( iResult, + iSIModelBankDB->UpdateModelBankIfInvalidL( iModelBankID ); + HandleLoadModelsL( iModelBankID ); + ); + } + + if ( iResult != KErrNone ) + { + // iModelBankDB needs to be reset also since multiple model banks can + // be loaded and this may not be the first model bank. + iSIModelBankDB->ResetAndDestroy(); + iState = ESiPluginIdle; + + iControllerIf.SendSrsEvent( KUidAsrEventLoadModels, iResult ); + } + } + break; + + case KRecognize: + TRAP( iResult, HandleRecognizeL() ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KRecognize. HandleLoadGrammarL Left with error [%d]", iResult ); + + if ( iResult != KErrAsrNoMatch ) + { + RecognitionReset(); + } + iControllerIf.SendSrsEvent( KUidAsrEventRecognition, iResult ); + } + break; + + case KRecord: + TRAP( iResult, HandleRecordL( iRecordTime ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KRecord. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventRecord, iResult ); + } + break; + + case KRemoveGrammar: + TRAP( iResult, HandleRemoveGrammarL( iGrammarID ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveGrammar, iResult ); + break; + + case KRemoveLexicon: + TRAP( iResult, HandleRemoveLexiconL( iLexiconID ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveLexicon, iResult ); + break; + + case KRemoveModelBank: + TRAP( iResult, HandleRemoveModelBankL( iModelBankID ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveModelBank, iResult ); + break; + + case KRemoveModel: + TRAP( iResult, HandleRemoveModelL( iModelBankID, iModelID ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemoveModel, iResult ); + break; + + case KRemovePronunciation: + TRAP( iResult, HandleRemovePronunciationL( iLexiconID, iPronunciationID ) ); + iControllerIf.SendSrsEvent( KUidAsrEventRemovePronunciation, iResult ); + break; + + case KRemoveRule: + TRAP( iResult, HandleRemoveRuleL( iGrammarID, iRuleID ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KRemoveRule. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRule, iResult ); + } + break; + case KRemoveRules: + TRAP( iResult, HandleRemoveRulesL( iGrammarID, *iRuleIDs ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KRemoveRules. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventRemoveRules, iResult ); + } + break; + + case KTrain: + TRAP( iResult, HandleTrainL( iModelBankID ) ); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KTrain. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventTrain, iResult ); + } + break; + + case KUnloadRule: + TRAP( iResult, HandleUnloadRuleL(iGrammarID, iRuleID)); + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KUnloadRule. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventUnloadRule, iResult ); + } + break; + + + // SI Component + case KAdapt: + TRAP( iResult, HandleAdaptL(*iSIClientResultSet ,iCorrect)) ; + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KAdapt. HandleLoadGrammarL Left with error [%d]", iResult ); + + iControllerIf.SendSrsEvent( KUidAsrEventAdapt , iResult ); + } + break; + /* case KSIAddPronunciation: + TRAP(iResult, HandleAddPronunciationL(iLexiconID, iTrainTextPtr, + iLanguage, iPronunciationIDPtr)) ; + iControllerIf.SendSrsEvent(KUidAsrEventAddPronunciation, iResult); + break; + */ + case KAddRuleVariant: + TRAP( iResult, HandleAddRuleVariantL( iGrammarID, iLexiconID, *iPronunciationIDs, iRuleID, *iRuleVariantIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventAddRuleVariant, iResult ); + break; + /* + case KAddVoiceTag: + TRAP(iResult, HandleAddVoiceTagL( *iTrainArray, *iLanguageArray, + iLexiconID, iGrammarID, iRuleIDPtr)) ; + iControllerIf.SendSrsEvent(KUidAsrEventAddVoiceTag, iResult); + break; + */ + case KAddVoiceTags: + TRAP( iResult, HandleAddVoiceTagsL( iTrainArrays, *iLanguageArray, iLexiconID, + iGrammarID /* ,*iRuleIDs */) ); + // AddVoiceTags contain several async functions, + // KUidAsrEventAddVoiceTags will be sent when the AddVoiceTags complete + if ( iResult != KErrNone ) + { + RUBY_DEBUG1( "CSIControllerPlugin::RunL. KAddVoiceTags. HandleLoadGrammarL Left with error [%d]", iResult ); + + // Clean up the iTrainArrays + if ( iTrainArrays ) + { + iTrainArrays->ResetAndDestroy(); + iTrainArrays->Close(); + delete iTrainArrays; + iTrainArrays = NULL; + } + // Send error message + iControllerIf.SendSrsEvent( KUidAsrEventAddVoiceTags, iResult ); + } + iTrainArrays = NULL; + break; + +#ifdef __SINDE_TRAINING + case KAddSindeVoiceTags: + RUBY_DEBUG0( "CSIControllerPlugin::RunL KAddSindeVoiceTags" ); + +#ifdef _DEBUG + for ( TInt i = 0; i < iLanguageArrayArray->Count(); i++ ) + { + RUBY_DEBUG1( "Contents of element %d:", i ); + RLanguageArray langArr = (*iLanguageArrayArray)[i]; + for ( TInt j = 0; j < langArr.Count(); j++ ) + { + RUBY_DEBUG2( "Index: %d Language: %d", j, langArr[j] ); + } + } +#endif // _DEBUG + + TRAP( iResult, HandleAddSindeVoiceTagsL( iTrainArrays, *iLanguageArrayArray, iLexiconID, iGrammarID ) ); + + if ( iResult != KErrNone ) + { + iTrainArrays->ResetAndDestroy(); + iTrainArrays->Close(); + delete iTrainArrays; + iTrainArrays = NULL; + + // Send error message + iControllerIf.SendSrsEvent( KUidAsrEventAddVoiceTags, iResult ); + } + iTrainArrays = NULL; + break; +#endif + case KCreateRule: + TRAP(iResult, HandleCreateRuleL( iGrammarID,*iRuleIDPtr ) ); + iControllerIf.SendSrsEvent( KUidAsrEventCreateRule, iResult ); + break; + /* case KSIRecognize: + TRAP(iResult, HandleRecognizeL(*(CSIClientResultSet*)iSIClientResultSet)) ; + // iControllerIf.SendSrsEvent(KUidAsrEventSIRecognize, iResult); + break; + */ + case KEndRecord: + TRAP( iResult, HandleEndRecordL( ) ); + iControllerIf.SendSrsEvent( KUidAsrEventEndRecord, iResult ); + break; + case KUnloadGrammar: + TRAP( iResult, HandleUnloadGrammarL( iGrammarID ) ) ; + // UnloadGrammar contain several async functions, + // KUidAsrEventUnloadGrammar will be sent when the UnloadGrammar complete + //iControllerIf.SendSrsEvent(KUidAsrEventUnloadGrammar, iResult); + break; + /*case KUpdateGrammarAndLexicon: + TRAP(iResult, HandleUpdateGrammarAndLexiconL(iSITtpWordList,iLexiconID,iGrammarID,*iRuleIDs)); + iControllerIf.SendSrsEvent(KUidAsrEventUpdateGrammarAndLexicon, iResult); + + break; + */ + + case KPreStartSampling: + TRAP( iResult, HandlePreStartSamplingL() ); + iControllerIf.SendSrsEvent( KUidAsrEventPreStartSampling, iResult ); + break; + + default: + // No action + break; + } +} + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::DoAsynch +// This method completes the request status and set the object active +// to provide asynchronous behavior. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::DoAsynch() + { + TRequestStatus* pRS = &iStatus; + User::RequestComplete( pRS, KErrNone ); + SetActive(); + } + +// ============================SI MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AdaptL +// Calls the devasr for adaptation +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AdaptL( CSIClientResultSet& aResultSet ,TInt aCorrect ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AdaptL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KAdapt; + + iSIClientResultSet = &aResultSet; + iCorrect = aCorrect; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleAdaptL +// Calls the devasr for adaptation +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleAdaptL( CSIClientResultSet& aResultSet, + TInt aCorrect ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleAdaptL" ); + if ( iState == ESiPluginRecognize ) + { + iSIDatabase->BeginTransactionL(); + if ( iSIGrammarDB->IsGrammarLoaded() ) + + { + iDevASR->AdaptL( aResultSet.SIResultSet(), aCorrect ); + } + else + { + // Either the loaded grammars are empty (contains no rule) or + // all rules have been unloaded. No need to proceed any further. + iSIDatabase->CommitChangesL( EFalse ); + + User::Leave( KErrAsrNoMatch ); + } + + iSIDatabase->CommitChangesL( EFalse ); + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddPronunciationL +// Adds a new pronunciation for the given model into the specified lexicon. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddPronunciationL( TSILexiconID /*aLexiconID*/, + const TDesC& /*aTrainText*/, + TLanguage /*aLanguage*/, + TSIPronunciationID& /*aPronunciationID*/) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddPronunciationL" ); + User::Leave( KErrNotSupported ); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddRuleVariantLtionL +// Adds a new rule variant for the given pronunciation into the specified grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddRuleVariantL( TSIGrammarID aGrammarID, + TSILexiconID aLexiconID, + RArray& aPronunciationIDs, + TSIRuleID aRuleID, + TSIRuleVariantID& aRuleVariantID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::AddRuleVariantL"); + + if ( IsActive() ) + { + User::Leave(KErrServerBusy); + } + iRequestFunction = KAddRuleVariant; + iGrammarID = aGrammarID; + iRuleID = aRuleID; + iLexiconID = aLexiconID; + iRuleVariantIDPtr = &aRuleVariantID; + iPronunciationIDs = &aPronunciationIDs; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleAddRuleVariantL +// Adds a new rule variant for the given pronunciation into the specified grammar. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleAddRuleVariantL( TSIGrammarID aGrammarID, + TSILexiconID aLexiconID, + RArray& aPronunciationIDs, + TSIRuleID aRuleID, + TSIRuleVariantID& aRuleVariantID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleAddRuleVariantL" ); + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->AddRuleVariantL( iClientUid, aGrammarID, aLexiconID, + aPronunciationIDs, aRuleID, aRuleVariantID ); + iSIDatabase->CommitChangesL( ETrue ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddVoiceTagL +// Trains a new voice tag. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddVoiceTagL( MDesCArray& /*aTrainArray*/, + RArray& /*aLanguageArray*/, + TSILexiconID /*aLexiconID*/, + TSIGrammarID /*aGrammarID*/, + TSIRuleID& /*aRuleID*/) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddVoiceTagL" ); + User::Leave( KErrNotSupported ); + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddVoiceTagsL +// Adds several new voice tags. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddVoiceTagsL( RPointerArray& aTrainArrays, + RArray& aLanguageArray, + TSILexiconID aLexiconID, + TSIGrammarID aGrammarID, + RArray& aRuleIDs) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::AddVoiceTagsL"); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + + // Use low priority for training (if training is not done from Voice Commands app) + if ( RProcess().SecureId() != KVoiceCommandsAppUid ) + { + RThread().SetPriority( EPriorityAbsoluteLow ); + } + + iState = ESiPluginTrainText; + // iTtpState=EAddVoiceTags; + + iRequestFunction = KAddVoiceTags ; + iLexiconID= aLexiconID; + iGrammarID = aGrammarID; + + iRuleIDs = &aRuleIDs; + iLanguageArray = &aLanguageArray; + iTrainArrays = &aTrainArrays; + + DoAsynch(); + } + +#ifdef __SINDE_TRAINING +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddSindeVoiceTagL +// Trains a new voice tag. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddSindeVoiceTagL( MDesCArray& /*aTrainArray*/, + RArray& /*aLanguageArray*/, + TSILexiconID /*aLexiconID*/, + TSIGrammarID /*aGrammarID*/, + TSIRuleID& /*aRuleID*/ ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddSindeVoiceTagL" ); + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::AddSindeVoiceTagsL +// Adds several new voice tags. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::AddSindeVoiceTagsL( RPointerArray& aTrainArrays, + RArray& aLanguageArray, + TSILexiconID aLexiconID, + TSIGrammarID aGrammarID, + RArray& aRuleIDs ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::AddSindeVoiceTagsL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + + // Use low priority for training (if training is not done from Voice Commands app) + if ( RProcess().SecureId() != KVoiceCommandsAppUid ) + { + RThread().SetPriority( EPriorityAbsoluteLow ); + } + + iState = ESiPluginTrainSinde; + + iRequestFunction = KAddSindeVoiceTags; + iLexiconID = aLexiconID; + iGrammarID = aGrammarID; + + // Store parameters for asynchronous processing + iRuleIDs = &aRuleIDs; + iLanguageArrayArray = &aLanguageArray; + iTrainArrays = &aTrainArrays; + + DoAsynch(); + } +#endif // __SINDE_TRAINING + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleAddVoiceTagsL +// Adds several new voice tags. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleAddVoiceTagsL( RPointerArray* aTrainArrays, + RArray& aLanguageArray, + TSILexiconID aLexiconID, + TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK("CSIControllerPlugin::HandleAddVoiceTagsL"); + // + // first test if both KLexiconID lexicon and KGrammarID are created + if ( IsLexiconIDInvalid( aLexiconID ) || IsGrammarIDInvalid( aGrammarID ) ) + { + User::Leave( KErrNotFound ); // no such grammar exist in Database + } + // Need to clean the iSITtpWordList before adding new arrays + delete iSITtpWordList; + iSITtpWordList = NULL; + iSITtpWordList = CSITtpWordList::NewL(); + if ( iState == ESiPluginTrainText ) + { + for ( TInt i=0; i < aTrainArrays->Count(); i++ ) + { + iSITtpWordList->AddL( ( *aTrainArrays )[i] ); + // If next AddL fails, we must not delete the objects twice - once in + // aTrainArray->ResetAndDestroy() and second time in ~CSITtpWordList. + ( *aTrainArrays )[i] = NULL; + } + aTrainArrays->ResetAndDestroy(); + aTrainArrays->Close(); + delete aTrainArrays; + aTrainArrays = NULL; + + // Set Max prnounication per word + iMaxNPronunsForWord.Reset(); + iMaxNPronunsForWord.Append( aLanguageArray.Count() ); + + RUBY_DEBUG1( "CSIControllerPlugin::AddVoiceTagsL(aLanguageArray.Count=%d)", aLanguageArray.Count() ); + + iDevASR->StartTrainingFromTextL(*iSITtpWordList,aLanguageArray,iMaxNPronunsForWord); + } + else + { + // Wrong state + User::Leave( KErrAsrInvalidState ); + } + } + +#ifdef __SINDE_TRAINING +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleAddVoiceTagsL +// Adds several new voice tags. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleAddSindeVoiceTagsL( RPointerArray* aTrainArrays, + RArray& aLanguageArray, + TSILexiconID aLexiconID, + TSIGrammarID aGrammarID ) + { + // First test if both KLexiconID lexicon and KGrammarID are created + if ( IsLexiconIDInvalid( aLexiconID ) || IsGrammarIDInvalid( aGrammarID ) ) + { + User::Leave( KErrNotFound ); // no such grammar exist in Database + } + + iSindeTrainer->AddSindeVoiceTagsL( aTrainArrays, aLanguageArray, + aLexiconID, aGrammarID, iModelBankID, + iClientUid, *iRuleIDs ); + + } +#endif // __SINDE_TRAINING + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::IsGrammarIDInvalid +// is the grammar id valid in the database +// ----------------------------------------------------------------------------- +// +TBool CSIControllerPlugin::IsGrammarIDInvalid( TSIGrammarID aGrammarID ) + { + TInt i(0); + RArray aGrammarIDs; + + TRAPD( error, + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->GetAllGrammarIDsL( aGrammarIDs ); + iSIDatabase->CommitChangesL( EFalse ); + ); // TRAPD + + if ( error == KErrNone ) + { + for( i = 0; i < aGrammarIDs.Count(); i++ ) + { + if ( aGrammarIDs[i] == aGrammarID ) + { + break; + } + if ( i == aGrammarIDs.Count() ) + { + aGrammarIDs.Close(); + return ETrue; // no such Lexicon exist in Database + } + } + } + aGrammarIDs.Close(); + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::IsLexiconIDInvalid +// is the lexicon id valid in the database +// ----------------------------------------------------------------------------- +// +TBool CSIControllerPlugin::IsLexiconIDInvalid( TSILexiconID aLexiconID ) + { + // first test if both KLexiconID lexicon and KLexiconID are created + TInt i(0); + RArray aLexiconIDs; + + TRAPD( error, + iSIDatabase->BeginTransactionL(); + iSILexiconDB->GetAllLexiconIDsL( aLexiconIDs ); + iSIDatabase->CommitChangesL( EFalse ); + ); //TRAPD + + if ( error == KErrNone ) + { + for( i = 0; i < aLexiconIDs.Count(); i++ ) + { + if ( aLexiconIDs[i] == aLexiconID ) + { + break; + } + if ( i == aLexiconIDs.Count() ) + { + aLexiconIDs.Close(); + return ETrue; // no such Lexicon exist in Database + } + } + } + + aLexiconIDs.Close(); + return EFalse; + } + + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::CreateRuleL +// Creates a new empty rule. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::CreateRuleL( TSIGrammarID aGrammarID, + TSIRuleID& aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::CreateRuleL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KCreateRule ; + iGrammarID = aGrammarID; + iRuleIDPtr= &aRuleID; + + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleCreateRuleL +// Creates a new empty rule. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleCreateRuleL( TSIGrammarID aGrammarID, + TSIRuleID& aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleCreateRuleL" ); + if ( iClientRegistered ) + { + iSIDatabase->BeginTransactionL(); + iSIGrammarDB->CreateRuleL( iClientUid, aGrammarID, aRuleID ); + iSIDatabase->CommitChangesL( EFalse ); + } + else + { + User::Leave( KErrAsrNotRegisted ); + } + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::EndRecordL +// End recordingEnds recording. Unlike Cancel(), this function may return a +// recognition result if adequate number of samples was already recorded. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::EndRecordL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::EndRecordL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KEndRecord ; + DoAsynch(); +} + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleEndRecordL +// End recordingEnds recording. Unlike Cancel(), this function may return a +// recognition result if adequate number of samples was already recorded. +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleEndRecordL() + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleEndRecordL" ); + iDevASR->EndRecord(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::UnloadGrammarL +// Unload a grammar from memory +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::UnloadGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::UnloadGrammarL" ); + + if ( IsActive() ) + { + User::Leave( KErrServerBusy ); + } + iRequestFunction = KUnloadGrammar ; + iGrammarID=aGrammarID; + DoAsynch(); + } + +// ----------------------------------------------------------------------------- +// CSIControllerPlugin::HandleUnloadGrammarL +// Unload a grammar from memory +// ----------------------------------------------------------------------------- +// +void CSIControllerPlugin::HandleUnloadGrammarL( TSIGrammarID aGrammarID ) + { + RUBY_DEBUG_BLOCK( "CSIControllerPlugin::HandleUnloadGrammarL" ); + + iSIDatabase->BeginTransactionL(); + CSICompiledGrammar* LoadedGrammar =iSIGrammarDB->FindGrammarL( aGrammarID ); + iSIDatabase->CommitChangesL( EFalse ); + + iDevASR->UnloadGrammar( *LoadedGrammar ); // async call to unload grammar in devasr + } + +// End of File