srsf/sisrscontrollerplugin/src/simodelbankdb.cpp
branchRCL_3
changeset 19 e36f3802f733
parent 0 bf1d17376201
equal deleted inserted replaced
18:cad71a31b7fc 19:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class handles the storage and access of user trained models
       
    15 *               and utterances into a database.  It performs checksum verification
       
    16 *               for the stored data.  It is also responsible for allocating memory
       
    17 *               when loading the models into the recognizer.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include <e32std.h>
       
    24 #include <e32base.h>
       
    25 #include <f32file.h>
       
    26 #include "siresourcehandler.h"
       
    27 #include "asrplugindataloader.h"
       
    28 #include "simodelbankdb.h"
       
    29 #include "rubydebug.h"
       
    30 
       
    31 // CONSTANTS
       
    32 const TInt KModelBankPackageType=3;
       
    33 const TInt KModelBankLanguageType=0;
       
    34 const TInt KModelBankStartPos=0;
       
    35 
       
    36 // _LIT(KModelFileName,"c:\\system\\Apps\\model_data\\qhmms_fxp"); // Commented out to remove "not referenced" warning
       
    37 // ============================ MEMBER FUNCTIONS ===============================
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 // CSIModelBankDB::CSIModelBankDB
       
    41 // C++ default constructor can NOT contain any code, that
       
    42 // might leave.
       
    43 // -----------------------------------------------------------------------------
       
    44 //
       
    45 CSIModelBankDB::CSIModelBankDB( RDbNamedDatabase& aDatabase, 
       
    46                                 RDbs& aDbSession,
       
    47                                 TInt aDrive )
       
    48                                : CSICommonDB(aDatabase, aDbSession, aDrive ),
       
    49                                  iAcousticModelPtr(0,0,0)
       
    50     {
       
    51     }
       
    52 
       
    53  // -----------------------------------------------------------------------------
       
    54 // CSIModelBankDB::ConstructL
       
    55 // Symbian 2nd phase constructor can leave.
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 void CSIModelBankDB::ConstructL()
       
    59     {
       
    60     RUBY_DEBUG_BLOCK( "CSIModelBankDB::ConstructL" );
       
    61 
       
    62     // Resource handler 
       
    63     CSIResourceHandler* resourceHandler = CSIResourceHandler::NewL();
       
    64     CleanupStack::PushL(resourceHandler);
       
    65     //  Data loader
       
    66     iDataLoader = CDataLoader::NewL( 
       
    67         *(resourceHandler->iDataFilenamePrefix), 
       
    68         *(resourceHandler->iDataFilenameSeperator),
       
    69         *(resourceHandler->iDataFilenamePostfix) );
       
    70     CleanupStack::PopAndDestroy(1); //resourceHandler
       
    71     }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CSIModelBankDB::NewL
       
    75 // Two-phased constructor.
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CSIModelBankDB* CSIModelBankDB::NewL( RDbNamedDatabase& aDatabase, 
       
    79                                       RDbs& aDbSession,
       
    80                                       TInt aDrive )
       
    81     {
       
    82     RUBY_DEBUG_BLOCK( "CSIModelBankDB::NewL" );
       
    83     
       
    84     CSIModelBankDB* self 
       
    85         = new( ELeave ) CSIModelBankDB( aDatabase, aDbSession, aDrive );
       
    86     CleanupStack::PushL( self );
       
    87     self->ConstructL();
       
    88     CleanupStack::Pop();	
       
    89     return self;
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // CSIModelBankDB::~CSIModelBankDB
       
    94 // Destructor
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 CSIModelBankDB::~CSIModelBankDB()
       
    98 {
       
    99 	// Delete all elements of the array before deleting the array
       
   100 	iModelBankArray.ResetAndDestroy();
       
   101 	iModelBankArray.Close();
       
   102 	
       
   103  	delete iDataLoader;
       
   104 }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CSIModelBankDB::GetAllAcousticModelsL
       
   108 // 
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 const CSIModelBank* CSIModelBankDB::GetAllAcousticModelsL( TSIModelBankID aModelBankID ) 
       
   112     {
       
   113     
       
   114     // Construct the table name using the provided model bank ID
       
   115     TBuf<40> KModelBankName(KSIModelBankTable);
       
   116     KModelBankName.AppendNumUC(aModelBankID);
       
   117     
       
   118     TBuf<100> KSQLStatement;
       
   119     // Declare a literal string to hold the SQL statement
       
   120     // SELECT  KHmmColumn, KHmmChecksumColumn FROM KModelBankName
       
   121     _LIT(KSQLSelect1, "SELECT ");
       
   122     _LIT(KSQLSelect2, " FROM ");
       
   123     
       
   124     KSQLStatement = KSQLSelect1;
       
   125     KSQLStatement.Append(KHmmColumn);
       
   126     KSQLStatement.Append(KNext);
       
   127     KSQLStatement.Append(KHmmChecksumColumn);
       
   128     KSQLStatement.Append(KSQLSelect2);
       
   129     KSQLStatement.Append(KModelBankName);
       
   130     
       
   131     RDbView view;
       
   132     CleanupClosePushL(view);
       
   133     User::LeaveIfError(view.Prepare(iDb, TDbQuery(KSQLStatement, EDbCompareNormal)));
       
   134     User::LeaveIfError(view.EvaluateAll());
       
   135     
       
   136     // Get column set for column ordinals
       
   137     CDbColSet* columns = view.ColSetL();
       
   138     TDbColNo hmm_col = columns->ColNo(KHmmColumn);
       
   139     TDbColNo hmmchecksum_col = columns->ColNo(KHmmChecksumColumn);
       
   140     delete columns;
       
   141     
       
   142     // Create a model bank object
       
   143     CSIModelBank* modelBank = CSIModelBank::NewLC(aModelBankID);
       
   144     
       
   145     TSIModelID modelID=KModelID;
       
   146     TInt length;
       
   147     TInt32 checksum;
       
   148     // After evaluation, the first call to NextL() is equivalent to FirstL()
       
   149     while ( view.NextL() )
       
   150         {
       
   151         // Retrieve the current row
       
   152         view.GetL();
       
   153         length = view.ColLength(hmm_col);
       
   154         checksum = view.ColUint32(hmmchecksum_col);
       
   155         
       
   156         // Read the acoustic model into a buffer
       
   157         TUint8* hmmBuf = new (ELeave) TUint8[length];
       
   158         CleanupStack::PushL(hmmBuf);
       
   159         TPtr8 hmmPtr(hmmBuf, 0, length);
       
   160         RDbColReadStream colReadStrm;
       
   161        	colReadStrm.OpenLC(view, hmm_col);
       
   162        	colReadStrm.ReadL(hmmPtr, length);
       
   163         // Cleanup colReadStrm
       
   164         CleanupStack::PopAndDestroy();
       
   165         
       
   166         if ( VerifyChecksum( hmmPtr, checksum) )
       
   167             {
       
   168             CSIModel* model = CSIModel::NewLC(modelID);
       
   169             HBufC8* aAcousticModel=HBufC8::NewL(length); 
       
   170             *aAcousticModel=hmmPtr;
       
   171             model->SetAcousticModel(aAcousticModel);
       
   172             modelBank->AddL((CSIModel*)model);
       
   173             //!
       
   174             // Cleanup aAcousticModel and hmmBuf
       
   175             CleanupStack::Pop();
       
   176             CleanupStack::PopAndDestroy();
       
   177             
       
   178             }
       
   179         else
       
   180             {
       
   181             User::Leave( KErrCorrupt );
       
   182             }
       
   183         }
       
   184     
       
   185     // Keep the reference of the modelBank
       
   186     //User::LeaveIfError(iModelBankArray.Append(modelBank));
       
   187     // Cleanup modelBank
       
   188     CleanupStack::Pop();
       
   189     
       
   190     // Cleanup view
       
   191     CleanupStack::PopAndDestroy();
       
   192     
       
   193     return modelBank;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CSIModelBankDB::AllAcousticModelsL
       
   198 // Loads all acoustic models within the specified model bank into a model bank
       
   199 // object, which is loaded into recognizer during recognition session.
       
   200 // -----------------------------------------------------------------------------
       
   201 //
       
   202 const CSIModelBank* CSIModelBankDB::AllAcousticModelsL( TSIModelBankID aModelBankID )
       
   203     {
       
   204     // Construct the table name using the provided model bank ID
       
   205     TBuf<40> KModelBankName(KSIModelBankTable);
       
   206     KModelBankName.AppendNumUC(aModelBankID);
       
   207     
       
   208     TBuf<100> KSQLStatement;
       
   209     // Declare a literal string to hold the SQL statement
       
   210     // SELECT  KHmmColumn, KHmmChecksumColumn FROM KModelBankName
       
   211     _LIT(KSQLSelect1, "SELECT * ");
       
   212     _LIT(KSQLSelect2, " FROM ");
       
   213     
       
   214     KSQLStatement = KSQLSelect1;
       
   215     //	KSQLStatement.Append(KHmmColumn);
       
   216     //	KSQLStatement.Append(KNext);
       
   217     //	KSQLStatement.Append(KHmmChecksumColumn);
       
   218     KSQLStatement.Append(KSQLSelect2);
       
   219     KSQLStatement.Append(KModelBankName);
       
   220     RDbView view;
       
   221     CleanupClosePushL(view);
       
   222     User::LeaveIfError(view.Prepare(iDb, TDbQuery(KSQLStatement, EDbCompareNormal)));
       
   223     User::LeaveIfError(view.EvaluateAll());
       
   224     
       
   225     // Get column set for column ordinals
       
   226     CDbColSet* columns = view.ColSetL();
       
   227     TDbColNo hmm_col = columns->ColNo(KHmmColumn);
       
   228     TDbColNo hmmchecksum_col = columns->ColNo(KHmmChecksumColumn);
       
   229     delete columns;
       
   230     
       
   231     // Create a model bank object
       
   232     CSIModelBank* modelBank = CSIModelBank::NewLC(aModelBankID);
       
   233     
       
   234     TSIModelID modelID=KModelID;
       
   235     TInt length;
       
   236     TInt32 checksum;
       
   237     // After evaluation, the first call to NextL() is equivalent to FirstL()
       
   238     while ( view.NextL() )
       
   239         {
       
   240         // Retrieve the current row
       
   241         view.GetL();
       
   242         length = view.ColLength(hmm_col);
       
   243         checksum = view.ColUint32(hmmchecksum_col);
       
   244         
       
   245         // Read the acoustic model into a buffer
       
   246         TUint8* hmmBuf = new (ELeave) TUint8[length];
       
   247         CleanupStack::PushL(hmmBuf);
       
   248         TPtr8 hmmPtr(hmmBuf, 0, length);
       
   249         RDbColReadStream colReadStrm;
       
   250        	colReadStrm.OpenLC(view, hmm_col);
       
   251        	colReadStrm.ReadL(hmmPtr, length);
       
   252         // Cleanup colReadStrm
       
   253         CleanupStack::PopAndDestroy();
       
   254 
       
   255 #ifdef __SIND_HMMS_TO_FILE
       
   256         {
       
   257         TInt error( KErrNone );
       
   258         RFile sampleFile; 
       
   259         RFs fileSession; 
       
   260         User::LeaveIfError( fileSession.Connect() );
       
   261 
       
   262         _LIT( KCDrive,"c:\\" ); 
       
   263         _LIT( KFileName, "data\\rec\\hmm_%08d.raw" ); 
       
   264         _LIT( KStartOfYear, "20060101:000000.000000" ); 
       
   265         TTime startOfYear( KStartOfYear ); 
       
   266         TTimeIntervalSeconds secondsSince; 
       
   267         TTime nowtime; 
       
   268         nowtime.UniversalTime(); 
       
   269         nowtime.SecondsFrom( startOfYear, secondsSince );
       
   270 
       
   271         TFileName fileName; 
       
   272         fileName.Append( KCDrive ); 
       
   273         fileName.AppendFormat( KFileName, secondsSince.Int() ); 
       
   274         error = sampleFile.Replace( fileSession, fileName, EFileWrite );
       
   275         if ( !error ) 
       
   276             {
       
   277             TPtr8 ptr( hmmBuf, length ); 
       
   278             ptr.SetLength( length ); 
       
   279             sampleFile.Write( ptr );
       
   280             sampleFile.Close();
       
   281             }   
       
   282         fileSession.Close();
       
   283         }
       
   284 #endif
       
   285         
       
   286         if ( VerifyChecksum( hmmPtr, checksum) )
       
   287             {
       
   288             CSIModel* model = CSIModel::NewLC(modelID);
       
   289             HBufC8* aAcousticModel=HBufC8::NewL(length); 
       
   290             *aAcousticModel=hmmPtr;
       
   291             SetAcousticModelL(aAcousticModel->Des());
       
   292             model->SetAcousticModel(aAcousticModel);
       
   293             modelBank->AddL((CSIModel*)model);
       
   294             //!
       
   295             // Cleanup aAcousticModel and hmmBuf
       
   296             CleanupStack::Pop();
       
   297             CleanupStack::PopAndDestroy();
       
   298             }
       
   299         else
       
   300             {
       
   301             User::Leave( KErrCorrupt );
       
   302             }
       
   303         }
       
   304     
       
   305     // Keep the reference of the modelBank
       
   306     User::LeaveIfError(iModelBankArray.Append(modelBank));
       
   307     // Cleanup modelBank
       
   308     CleanupStack::Pop();
       
   309     // Cleanup view
       
   310     CleanupStack::PopAndDestroy();
       
   311     
       
   312     return modelBank;
       
   313     }
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CSIModelBankDB::AllModelCountL
       
   317 // Returns the total number of models in the system (all model banks).
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 TInt CSIModelBankDB::AllModelCountL()
       
   321     {
       
   322     TBuf<100> KSQLStatement;
       
   323     // Declare a literal string to hold the SQL statement
       
   324     // SELECT KCounterColumn FROM KModelBankIdTable WHERE KUsedColumn = KUsed
       
   325     _LIT(KSQLSelect1, "SELECT ");
       
   326     _LIT(KSQLSelect2, " FROM ");
       
   327     _LIT(KSQLSelect3, " WHERE ");
       
   328     
       
   329     KSQLStatement = KSQLSelect1;
       
   330     KSQLStatement.Append(KCounterColumn);
       
   331     KSQLStatement.Append(KSQLSelect2);
       
   332     KSQLStatement.Append(KModelBankIdTable);
       
   333     KSQLStatement.Append(KSQLSelect3);
       
   334     KSQLStatement.Append(KUsedColumn);
       
   335     KSQLStatement.Append(KEqual);
       
   336     KSQLStatement.AppendNum(KUsed);
       
   337     
       
   338     RDbView view;
       
   339     CleanupClosePushL(view);
       
   340     User::LeaveIfError(view.Prepare(iDb, TDbQuery(KSQLStatement, EDbCompareNormal)));
       
   341     User::LeaveIfError(view.EvaluateAll());
       
   342     
       
   343     // Get column set for column ordinals
       
   344     CDbColSet* columns = view.ColSetL();
       
   345     
       
   346     delete columns;
       
   347     
       
   348     TInt counter = 0;
       
   349     // After evaluation, the first call to NextL() is equivalent to FirstL()
       
   350     while ( view.NextL() )
       
   351         {
       
   352         // Retrieve the current row
       
   353         view.GetL();
       
   354         //counter += view.ColInt(counter_col);
       
   355         //!
       
   356         counter ++;//=view.ColInt(used_col); 
       
   357         }
       
   358     
       
   359     // Cleanup view
       
   360     CleanupStack::PopAndDestroy();
       
   361     
       
   362     return counter;
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CSIModelBankDB::CreateIDTableL
       
   367 // Creates a new model bank ID table in the database.
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 void CSIModelBankDB::CreateIDTableL()
       
   371     {
       
   372     // Invoke function in the base class CSICommonDB.
       
   373     CSICommonDB::CreateIDTableL(KModelBankIdTable, KModelBankIdColumn, KModelBankIndex);
       
   374     };
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CSIModelBankDB::CreateModelBankL
       
   378 // Creates a new model bank table in the database.
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 TSIModelBankID CSIModelBankDB::CreateModelBankL( TUid aClientUid )
       
   382     {
       
   383     RUBY_DEBUG_BLOCK( "CSIModelBankDB::CreateModelBankL" );
       
   384     
       
   385     // Model bank is already exist in the 
       
   386     RArray<TSIModelBankID> aExistModelBankIDs;
       
   387     CleanupClosePushL( aExistModelBankIDs );
       
   388     GetAllClientModelBankIDsL(aClientUid,aExistModelBankIDs);
       
   389     
       
   390     
       
   391     if(aExistModelBankIDs.Count()>0) {
       
   392         TSIModelBankID aExistModelBankID=aExistModelBankIDs[0];	
       
   393         CleanupStack::PopAndDestroy( &aExistModelBankIDs );
       
   394         return aExistModelBankID;
       
   395         }
       
   396     CleanupStack::PopAndDestroy( &aExistModelBankIDs );
       
   397     
       
   398     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSIModelBank ) ) );
       
   399     
       
   400     // Generate a new model bank ID
       
   401     TSIModelBankID modelBankID = STATIC_CAST(TSIModelBankID,CreateNewIDL(KModelBankIdTable, KModelBankIdColumn, aClientUid));
       
   402     // Construct the table name using the new model bank ID
       
   403     TBuf<40> KModelBankName(KSIModelBankTable);
       
   404     KModelBankName.AppendNumUC(modelBankID);
       
   405     // Create a table definition
       
   406     CDbColSet* columns=CDbColSet::NewLC();
       
   407     
       
   408     // add the columns  
       
   409     // 1) Binary data, 2) binary data size
       
   410     columns->AddL(TDbCol(KHmmColumn,EDbColLongBinary));
       
   411     columns->AddL(TDbCol(KHmmChecksumColumn,EDbColUint32));
       
   412     
       
   413     // Create a table
       
   414     TInt err =iDb.CreateTable(KModelBankName,*columns);
       
   415     
       
   416     if ( err != KErrNone )
       
   417         {
       
   418         // Failed to create the table.
       
   419         // Need to release the new ModelBank ID and leave.
       
   420         ReleaseIdL(KModelBankIdTable, KModelBankIdColumn, modelBankID);
       
   421         User::Leave(err);
       
   422         }
       
   423     
       
   424     // cleanup the column set
       
   425     CleanupStack::PopAndDestroy();
       
   426     
       
   427     // Put and empty Modelbank inside
       
   428         {
       
   429         //!!! Use the default model file to construct	
       
   430         //!
       
   431         HBufC8 *bf=NULL;		
       
   432         bf= iDataLoader->LoadData( KModelBankPackageType,KModelBankLanguageType,KModelBankStartPos,KMaxTUint32);
       
   433         // Modelbank file does not exist;
       
   434         if(bf==NULL)
       
   435             User::Leave(KErrNotFound);
       
   436         CleanupStack::PushL(bf);
       
   437         
       
   438         iAcousticModelPtr.Set(bf->Des());
       
   439         //.Set(_L8("empty"));
       
   440         //iAcousticModelPtr=(_L8("empty"));
       
   441         // Always 1 for each model bank
       
   442         //TSIModelID modelID=KModelID; 
       
   443         
       
   444         TInt32 hmmChecksum = CalculateChecksum(iAcousticModelPtr);
       
   445         
       
   446         // Open model bank table
       
   447         RDbTable dbTable;		// Provides access to table data as a rowset
       
   448         User::LeaveIfError(dbTable.Open(iDb, KModelBankName, RDbTable::EUpdatable));
       
   449         CleanupClosePushL(dbTable);
       
   450         
       
   451         // Get column set for column ordinals
       
   452         columns = dbTable.ColSetL();
       
   453         TDbColNo hmm_col = columns->ColNo(KHmmColumn);
       
   454         TDbColNo hmmchecksum_col = columns->ColNo(KHmmChecksumColumn);
       
   455         delete columns;
       
   456         
       
   457         // 		 No, insert new row
       
   458         dbTable.InsertL();
       
   459         dbTable.SetColL(hmm_col, iAcousticModelPtr);
       
   460         
       
   461         dbTable.SetColL(hmmchecksum_col, hmmChecksum);
       
   462         
       
   463         // Write the updated row
       
   464         TRAPD(err, dbTable.PutL());
       
   465         if( err != KErrNone )
       
   466             {
       
   467             // Error: cancel update
       
   468             dbTable.Cancel();
       
   469             dbTable.Reset();
       
   470             User::Leave(err);
       
   471             }
       
   472         
       
   473         // Cleanup bf dbTable 
       
   474         CleanupStack::PopAndDestroy(2);
       
   475         // Free up resources
       
   476         Reset();
       
   477         }
       
   478         
       
   479     iDbSession.FreeReservedSpace( iDrive );
       
   480         
       
   481     //AllAcousticModelsL(modelBankID);
       
   482     return modelBankID;
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CSIModelBankDB::GetAllClientModelBankIDsL
       
   487 // This function returns all model bank IDs owned by the specified client.
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 void CSIModelBankDB::GetAllClientModelBankIDsL( TUid aClientUid,
       
   491                                                 RArray<TSIModelBankID>& aModelBankIDs )
       
   492     {
       
   493     // This is a hack to get the id aligned to 4-byte boundary,
       
   494     // for some reason this does not happen in winscw build if 
       
   495     // TSIModelBankID is taken from stack.
       
   496     TSIModelBankID* id = new (ELeave) TSIModelBankID;
       
   497     CleanupStack::PushL( id );
       
   498     
       
   499     RArray<TUint32> ix;
       
   500     ix.Reset();
       
   501     GetAllClientIDsL(KModelBankIdTable, KModelBankIdColumn, aClientUid, ix);
       
   502     for(TInt i=0;i<ix.Count();i++) 
       
   503         {
       
   504         *id = STATIC_CAST( TSIModelBankID, ix[i] );
       
   505         aModelBankIDs.Append( *id );
       
   506         }
       
   507     ix.Close();
       
   508     CleanupStack::PopAndDestroy( id );
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CSIModelBankDB::GetAllModelBankIDsL
       
   513 // This function returns all model bank IDs in the database.
       
   514 // -----------------------------------------------------------------------------
       
   515 //
       
   516 void CSIModelBankDB::GetAllModelBankIDsL( RArray<TSIModelBankID>& aModelBankIDs )
       
   517     {
       
   518     // This is a hack to get the id aligned to 4-byte boundary,
       
   519     // for some reason this does not happen in winscw build if 
       
   520     // TSIModelBankID is taken from stack.
       
   521     TSIModelBankID* id = new ( ELeave ) TSIModelBankID;
       
   522     CleanupStack::PushL( id );
       
   523     
       
   524     RArray<TUint32> ix;
       
   525     ix.Reset();
       
   526     GetAllIDsL( KModelBankIdTable, KModelBankIdColumn, ix );
       
   527     for ( TInt i = 0; i < ix.Count(); i++ ) 
       
   528         { 
       
   529         *id = STATIC_CAST( TSIModelBankID, ix[i] );
       
   530         aModelBankIDs.Append( *id );
       
   531         }
       
   532     ix.Close();
       
   533     CleanupStack::PopAndDestroy( id );
       
   534     }
       
   535 
       
   536 // -----------------------------------------------------------------------------
       
   537 // CSIModelBankDB::GetAllModelIDsL
       
   538 // This function returns all model IDs within the specified model bank. It's
       
   539 // expected that the client has already done allocation on aModelIDs array object.
       
   540 // -----------------------------------------------------------------------------
       
   541 //
       
   542 void CSIModelBankDB::GetAllModelIDsL( TSIModelBankID /*aModelBankID*/,
       
   543                                      RArray<TSIModelID>& aModelIDs )
       
   544     {
       
   545     // Only one id , and it is KModelID
       
   546     aModelIDs.Append(KModelID);	
       
   547     }
       
   548 	
       
   549 // -----------------------------------------------------------------------------
       
   550 // CSIModelBankDB::IsModelBankValidL
       
   551 // Checks if the specified model bank table exists in the database and also verify
       
   552 // ownership.
       
   553 // -----------------------------------------------------------------------------
       
   554 //
       
   555 TBool CSIModelBankDB::IsModelBankValidL( TUid aClientUid,
       
   556                                          TSIModelBankID aModelBankID )
       
   557     {
       
   558     VerifyOwnershipL(aClientUid, KModelBankIdTable, KModelBankIndex, aModelBankID);
       
   559     return ETrue;
       
   560     }
       
   561 
       
   562 // -----------------------------------------------------------------------------
       
   563 // CSIModelBankDB::IsModelValidL
       
   564 // Checks if the specified model exists in the specified model bank table.
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 TBool CSIModelBankDB::IsModelValidL( TSIModelBankID /*aModelBankID*/,
       
   568                                      TSIModelID aModelID )
       
   569     {
       
   570     // Assume that ModelBankd ID is valid
       
   571     if (aModelID==KModelID)
       
   572         {
       
   573         return ETrue;
       
   574         }
       
   575     else
       
   576         {
       
   577         return EFalse;
       
   578         }
       
   579     }
       
   580     
       
   581 // -----------------------------------------------------------------------------
       
   582 // CSIModelBankDB::UpdateModelBankIfInvalidL
       
   583 // Validate the adapted model bank against ROM version and update if not valid.
       
   584 // -----------------------------------------------------------------------------
       
   585 //
       
   586 void CSIModelBankDB::UpdateModelBankIfInvalidL( TSIModelBankID aModelBankID )
       
   587     {    
       
   588     RUBY_DEBUG_BLOCK( "CSIModelBankDB::UpdateModelBankIfInvalidL" );
       
   589     
       
   590     const TUint KModelBankHeaderSize(20);
       
   591     
       
   592     HBufC8 *bf = iDataLoader->LoadData( KModelBankPackageType,
       
   593                                         KModelBankLanguageType,
       
   594                                         KModelBankStartPos,
       
   595                                         KMaxTUint32 );
       
   596     
       
   597     if( bf == NULL )
       
   598         {
       
   599         // Modelbank file does not exist;
       
   600         User::Leave( KErrNotFound );
       
   601         }
       
   602         
       
   603     CleanupStack::PushL( bf );
       
   604     
       
   605     TPtr8 origModelPtr( bf->Des() );
       
   606 
       
   607     // Compare phoneme definitions
       
   608     TBool areEqual( EFalse );
       
   609     
       
   610     TRAPD( error, 
       
   611         const CSIModelBank* adaptedModelBank = GetAllAcousticModelsL( aModelBankID );
       
   612         CleanupStack::PushL( (CSIModelBank*)adaptedModelBank );
       
   613 
       
   614         TPtrC8 adaptedModelPtr = adaptedModelBank->AtL(0).AcousticModel();
       
   615         
       
   616         // 1. Compare size of phoneme definition
       
   617         TInt adaptedSize = adaptedModelPtr[18];
       
   618         adaptedSize |= adaptedModelPtr[19] << 8;
       
   619             
       
   620         TInt origSize = origModelPtr[18];
       
   621         origSize |= origModelPtr[19] << 8;
       
   622         
       
   623         if ( adaptedSize == origSize )
       
   624             {
       
   625             // 2. compare content of phoneme definitions
       
   626             TInt size = origSize + KModelBankHeaderSize;
       
   627             if ( Mem::Compare( origModelPtr.Ptr(), size, adaptedModelPtr.Ptr(), size ) == 0 )
       
   628                 {
       
   629                 areEqual = ETrue;
       
   630                 }
       
   631             }
       
   632 
       
   633         CleanupStack::PopAndDestroy( (CSIModelBank*)adaptedModelBank );
       
   634     );
       
   635     
       
   636     // GetAllAcousticModelsL will leave with KErrCorrupt if checksum doesn't match
       
   637     // This case should be handled by updating model bank
       
   638     if ( error != KErrNone && error != KErrCorrupt )
       
   639         {
       
   640         User::Leave( error );
       
   641         }
       
   642     
       
   643     if ( !areEqual )
       
   644         {
       
   645         // replace the adapted model bank with the original model bank
       
   646         RUBY_DEBUG0("phoneme definitions changed or model bank corrupted, update models" );
       
   647         
       
   648         SetAcousticModelL( origModelPtr );
       
   649         SaveModelL( aModelBankID );
       
   650         }
       
   651 
       
   652     CleanupStack::PopAndDestroy( bf );
       
   653     }
       
   654     
       
   655 // -----------------------------------------------------------------------------
       
   656 // CSIModelBankDB::GetUtteranceDurationL
       
   657 //
       
   658 // -----------------------------------------------------------------------------
       
   659 //
       
   660 void CSIModelBankDB::GetUtteranceDurationL( TSIModelBankID /*aModelBankID*/, 
       
   661                                             TSIModelID /*aModelID*/,
       
   662                                             TTimeIntervalMicroSeconds32& /*aDuration*/ )
       
   663     {
       
   664     User::Leave(KErrNotSupported);
       
   665     }
       
   666 
       
   667 // -----------------------------------------------------------------------------
       
   668 // CSIModelBankDB::ModelCountL
       
   669 // Returns the number of models in the specified model bank.
       
   670 // -----------------------------------------------------------------------------
       
   671 //
       
   672 TInt CSIModelBankDB::ModelCountL( TSIModelBankID /*aModelBankID*/ )
       
   673     {
       
   674     
       
   675     //User::Leave(KErrNotSupported);
       
   676     return 1;
       
   677     // one model per modelbank by defination
       
   678     }
       
   679 
       
   680 // -----------------------------------------------------------------------------
       
   681 // CSIModelBankDB::RemoveModelBankL
       
   682 // Deletes a model bank table from the database.
       
   683 // -----------------------------------------------------------------------------
       
   684 //
       
   685 void CSIModelBankDB::RemoveModelBankL( TUid aClientUid,
       
   686                                        TSIModelBankID aModelBankID )
       
   687     {
       
   688     VerifyOwnershipL(aClientUid, KModelBankIdTable, KModelBankIndex, aModelBankID);
       
   689     
       
   690     TInt diskSpace = ( ModelCountL(aModelBankID) * sizeof( CSIModel ) )
       
   691         + sizeof( CSIModelBank );
       
   692     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) );
       
   693     
       
   694     // Construct the table name using the provided model bank ID
       
   695     TBuf<40> KModelBankName(KSIModelBankTable);
       
   696     KModelBankName.AppendNumUC(aModelBankID);
       
   697     
       
   698     TBuf<50> KSQLStatement;
       
   699     // Declare a literal string to hold the SQL statement
       
   700     // DROP TABLE KModelBankName
       
   701     _LIT(KSQLDelete1, "DROP TABLE ");
       
   702     
       
   703     KSQLStatement = KSQLDelete1;
       
   704     KSQLStatement.Append(KModelBankName);
       
   705     
       
   706     User::LeaveIfError(iDb.Execute(KSQLStatement));
       
   707     
       
   708     // Release the ModelBank ID
       
   709     ReleaseIdL(KModelBankIdTable, KModelBankIdColumn, aModelBankID);
       
   710     
       
   711     // Cancel free disk space request
       
   712     iDbSession.FreeReservedSpace( iDrive );
       
   713     }
       
   714 
       
   715 // -----------------------------------------------------------------------------
       
   716 // CSIModelBankDB::RemoveModelL
       
   717 // Removes a model from the model bank table by marking it as "not used".
       
   718 // -----------------------------------------------------------------------------
       
   719 //
       
   720 void CSIModelBankDB::RemoveModelL( TUid /*aClientUid*/,
       
   721                                    TSIModelBankID /*aModelBankID*/,
       
   722                                    TSIModelID /*aModelID*/ )
       
   723     {
       
   724     User::Leave(KErrNotSupported);
       
   725     }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // CSIModelBankDB::Reset
       
   729 // Deallocates the temporary memory allocated during training.
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 void CSIModelBankDB::Reset()
       
   733     {
       
   734     iAcousticModelPtr.Set(0,0,0);
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CSIModelBankDB::Reset
       
   739 // Deallocates the temporary memory allocated during recognition.
       
   740 // -----------------------------------------------------------------------------
       
   741 //
       
   742 void CSIModelBankDB::ResetAndDestroy()
       
   743     {
       
   744     iModelBankArray.ResetAndDestroy();
       
   745     }
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // CSIModelBankDB::SaveModelL
       
   749 // Saves the trained model in the temporary memory into the database.
       
   750 // -----------------------------------------------------------------------------
       
   751 //
       
   752 TSIModelID CSIModelBankDB::SaveModelL( TSIModelBankID aModelBankID )
       
   753     {
       
   754     if ( iAcousticModelPtr.Length() <= 0 )
       
   755         {
       
   756         User::Leave(KErrNotReady);
       
   757         }
       
   758 
       
   759     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSIModel ) ) );
       
   760     
       
   761     // Always 1 for each model bank
       
   762     TSIModelID modelID=KModelID; 
       
   763     // Construct the table name using the provided model bank ID
       
   764     TBuf<40> KModelBankName(KSIModelBankTable);
       
   765     KModelBankName.AppendNumUC(aModelBankID);
       
   766     
       
   767     TInt32 hmmChecksum = CalculateChecksum(iAcousticModelPtr);
       
   768     
       
   769     // Open model bank table
       
   770     RDbTable dbTable;		// Provides access to table data as a rowset
       
   771     User::LeaveIfError(dbTable.Open(iDb, KModelBankName, RDbTable::EUpdatable));
       
   772     CleanupClosePushL(dbTable);
       
   773     
       
   774     // Get column set for column ordinals
       
   775     CDbColSet* columns = dbTable.ColSetL();
       
   776     TDbColNo hmm_col = columns->ColNo(KHmmColumn);
       
   777     TDbColNo hmmchecksum_col = columns->ColNo(KHmmChecksumColumn);
       
   778     delete columns;
       
   779     
       
   780     // 		Update it
       
   781     dbTable.FirstL(); 	
       
   782     dbTable.UpdateL();
       
   783     
       
   784     dbTable.SetColL(hmm_col, iAcousticModelPtr);
       
   785     dbTable.SetColL(hmmchecksum_col, hmmChecksum);
       
   786     
       
   787     // Write the updated row
       
   788     TRAPD(err, dbTable.PutL());
       
   789     if( err != KErrNone )
       
   790         {
       
   791         // Error: cancel update
       
   792         dbTable.Cancel();
       
   793         dbTable.Reset();
       
   794         User::Leave(err);
       
   795         }
       
   796     iDbSession.FreeReservedSpace( iDrive );
       
   797     // Cleanup dbTable
       
   798     CleanupStack::PopAndDestroy();
       
   799     // Free up resources
       
   800     Reset();
       
   801     
       
   802     return modelID;
       
   803     }
       
   804 
       
   805 // -----------------------------------------------------------------------------
       
   806 // CSIModelBankDB::SetAcousticModelL
       
   807 // Saves the acoustic model into a temporary memory during training.
       
   808 // -----------------------------------------------------------------------------
       
   809 //
       
   810 void CSIModelBankDB::SetAcousticModelL( const TPtr8& aAcousticModelBuf )
       
   811     {
       
   812     if ( aAcousticModelBuf.Length() <= 0 )
       
   813         {
       
   814         User::Leave(KErrNotReady);
       
   815         }
       
   816     
       
   817     iAcousticModelPtr.Set(aAcousticModelBuf);
       
   818     }
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // CSIModelBankDB::SetUtteranceDurationL
       
   822 // Saves the utterance duration of a trained model in temporary memory during
       
   823 // training.
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 void CSIModelBankDB::SetUtteranceDurationL( TInt /*aUtteranceDuration*/ )
       
   827     {
       
   828     User::Leave( KErrNotSupported );
       
   829     }
       
   830 
       
   831 // -----------------------------------------------------------------------------
       
   832 // CSIModelBankDB::CalculateChecksum
       
   833 // Calculates a checksum value for the given buffer.
       
   834 // -----------------------------------------------------------------------------
       
   835 //
       
   836 TInt32 CSIModelBankDB::CalculateChecksum( const TPtr8& aBuf )
       
   837     {
       
   838     TInt32 checksum = 0;
       
   839     TInt length = aBuf.Length();
       
   840     
       
   841     for( TInt i = 0; i < length; i++ )
       
   842         {
       
   843         checksum += aBuf[i];
       
   844         }
       
   845     return checksum;
       
   846     }
       
   847 
       
   848 // -----------------------------------------------------------------------------
       
   849 // CSIModelBankDB::VerifyChecksum
       
   850 // Verifies the checksum value for the given buffer by comparing it with the
       
   851 // provided aChecksum value.
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 TBool CSIModelBankDB::VerifyChecksum( const TPtr8& aBuf,
       
   855                                       TInt32 aChecksum )
       
   856     {
       
   857     TInt32 checksum = CalculateChecksum(aBuf);
       
   858     return (checksum == aChecksum);
       
   859     }
       
   860 
       
   861 
       
   862 // -----------------------------------------------------------------------------
       
   863 // Unit Test only
       
   864 // -----------------------------------------------------------------------------
       
   865 //
       
   866 #ifdef __CONSOLETEST__
       
   867 // Returns array of loaded model banks
       
   868 RPointerArray<CSIModelBank>& CSIModelBankDB::ModelBankArray()
       
   869     {
       
   870     return iModelBankArray;
       
   871     }
       
   872 
       
   873 #endif
       
   874 
       
   875 //  End of File