14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* FILE:		sub_phon.cpp
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  DATE MODIFIED:	31-Aug-07
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  DESCRIPTION:	Part of the  SREC graph compiler project source files.
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <iostream>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <sstream>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEBUG           0
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "sub_grph.h"
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "grxmldoc.h"
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ExpandPhonemes ( GRXMLDoc &doc )
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, wordId, phoneId, currId, newId, nextId, arcCount;
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Pronunciation pron;
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int pronCount;
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc *arcOne;
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    std::string modelLabel, word;
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        std::stringstream ss;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ss << SILENCE_CONTEXT;
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        modelLabel= ss.str();
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        silenceId = doc.addPhonemeToList(modelLabel);
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        std::stringstream ss;
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ss << INTRA_SILENCE_CONTEXT;
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        modelLabel= ss.str();
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        intraId = doc.addPhonemeToList(modelLabel);
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    UpdateVertexCount (0);
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arcCount= numArc;
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < arcCount; ii++) {
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        wordId= arc[ii]->GetInput();
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wordId >= 0) {
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    doc.findLabel(wordId, word );
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (IsSlot (word)) {
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        // std::cout << "Found slot "<< word <<std::endl;
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        newId= NewVertexId();
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        arcOne= CreateArc (NONE_LABEL, NONE_LABEL, arc[ii]->GetFromId(), newId);
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		arcOne->AssignCentre (NONE_LABEL);
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        nextId= NewVertexId();
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        //  special case
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        arcOne= CreateArc (-wordId, wordId, newId, nextId);
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		arcOne->AssignCentre (NONE_LABEL);
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        // (void) CreateArc (-wordId, NONE_LABEL, arc[ii]->GetFromId(), newId);
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        arcOne= CreateArc (WB_LABEL, NONE_LABEL, nextId, arc[ii]->GetToId());
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		arcOne->AssignCentre (NONE_LABEL);
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        // (void) CreateArc (WB_LABEL, wordId, newId, arc[ii]->GetToId());
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else {
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        pron.clear();
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        pron.lookup( *(doc.getVocabulary()), word );
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        pronCount = pron.getPronCount();
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        for (int jj= 0; jj < pronCount; jj++) {
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            currId= arc[ii]->GetFromId();
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            int modelCount = pron.getPhonemeCount(jj);
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            for (int kk= 0; kk < modelCount; kk++) {
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                newId= NewVertexId();
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                pron.getPhoneme(jj, kk, modelLabel);
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                //std::cout << "ExpandPhonemes adding "<< modelLabel <<std::endl;
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                phoneId = doc.addPhonemeToList( modelLabel );
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                arcOne= CreateArc (phoneId, NONE_LABEL, currId, newId);
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (phoneId == intraId)
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            arcOne->AssignCentre (silenceId);
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        else
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            arcOne->AssignCentre (phoneId);
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	                currId= newId;
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            }
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            arcOne= CreateArc (WB_LABEL, wordId, currId, arc[ii]->GetToId());
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    arcOne->AssignCentre (NONE_LABEL);
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        }
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        //  End of loop
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    arc[ii]->AssignInput (DISCARD_LABEL);   //  Delete original arc
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    RemoveDiscardedArcs ();
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	arc[ii]->AssignLeft (NONE_LABEL);
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	arc[ii]->AssignRight (NONE_LABEL);
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage ();
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::AddLeftContexts ()
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, rix, currId, leftC;
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage();
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguageReverse();
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() >= 0) {
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            currId= arc[ii]->GetFromId();
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rix= FindToIndex (currId);
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (rix >= 0) {
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                leftC= arc[backwardList[rix]]->GetCentre();
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[ii]->AssignLeft(leftC);
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (currId != startId)
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                printf ("Shouldn't get here (L) %d\n", currId);
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignLeft (NONE_LABEL);
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::AddRightContexts ()
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, rix, currId, rightC;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage();
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguageReverse();
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() >= 0) {
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            currId= arc[ii]->GetToId();
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rix= FindFromIndex (currId);
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (rix >= 0) {
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                rightC= arc[forwardList[rix]]->GetCentre();
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[ii]->AssignRight (rightC);
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                printf ("Shouldn't get here (R) %d\n", currId);
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignRight (NONE_LABEL);
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ExpandToHMMs ( GRXMLDoc &doc )
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, currId, newId, arcCount, left, right, centre;
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int modelCount;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc *arcOne;
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    UpdateVertexCount (0);
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arcCount= numArc;
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < arcCount; ii++) {
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        std::vector<int> modelSequence;
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (arc[ii]->GetInput() >= 0) {      //  i.e. proper phoneme
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            centre= arc[ii]->GetCentre();
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    left= arc[ii]->GetLeft();
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    right= arc[ii]->GetRight();
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    doc.getHMMSequence (centre, left, right, modelSequence);
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    modelCount = modelSequence.size();
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            std::cout << "HMM: " << centre << " number of HMMs = " << modelCount <<std::endl;
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (modelCount >= 0) {
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		currId= arc[ii]->GetFromId();
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		for (int jj= 0; jj < modelCount; jj++) {
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (jj == (modelCount - 1))
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        newId= arc[ii]->GetToId();
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    else
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        newId= NewVertexId();
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    arcOne= CreateArc (modelSequence[jj], NONE_LABEL, currId, newId);
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    arcOne->AssignCentre (arc[ii]->GetInput());
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    arcOne->AssignLeft (arc[ii]->GetLeft());
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    arcOne->AssignRight (arc[ii]->GetRight());
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    std::cout << "HMM phoneme: " << modelSequence[jj] << " ";
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    currId= newId;
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		}
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                std::cout << " centre " << arc[ii]->GetInput() << std::endl;
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[ii]->AssignInput (DISCARD_LABEL);       //  Delete original arc
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    RemoveDiscardedArcs ();
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage ();
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ExpandIntraWordSilence ( GRXMLDoc &doc )
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, fix, bix, firstId, newId, modelCount, followCount, currId, count;
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int left, centre, right;
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc *arcOne;
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage();
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguageReverse();
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    std::cout << "Intra sil search " << intraId << std::endl;
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count= numArc;
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < count; ii++) {
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetCentre() == intraId) {
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            std::cout << "Intra sil: " << arc[ii]->GetFromId() << " " << arc[ii]->GetToId() << std::endl;
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fix= FindToIndex (arc[ii]->GetFromId());
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (fix < 0)
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            while (fix < sortRevNum
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             && arc[backwardList[fix]]->GetToId() == arc[ii]->GetFromId()) {
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		//  left triphone
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                newId= NewVertexId();
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		left= arc[backwardList[fix]]->GetLeft();
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		centre= arc[ii]->GetLeft();
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		right= arc[ii]->GetRight();
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                std::vector<int> modelSequence;
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        doc.getHMMSequence (centre, left, right, modelSequence);
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        modelCount = modelSequence.size();
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                std::cout << "HMM: " << centre << " number of HMMs = " << modelCount <<std::endl;
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        if (modelCount >= 0) {
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    currId= arc[backwardList[fix]]->GetFromId();
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    for (int jj= 0; jj < modelCount; jj++) {
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        newId= NewVertexId();
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        arcOne= CreateArc (modelSequence[jj],
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project			    arc[backwardList[fix]]->GetOutput(), currId, newId);
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        arcOne->AssignCentre (centre);
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        std::cout << "HMM phoneme: " << modelSequence[jj] << " ";
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        currId= newId;
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    }
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    std::cout << " " << centre << std::endl;
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		}
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		firstId= newId;
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		//  right block
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                bix= FindFromIndex (arc[ii]->GetToId());
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (bix < 0)
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    return;
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (bix < sortNum
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 && arc[forwardList[bix]]->GetFromId() == arc[ii]->GetToId()) {
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix++;
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    //  right triphone
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    left= arc[ii]->GetLeft();
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    centre= arc[ii]->GetRight();
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    right= arc[forwardList[bix]]->GetRight();
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    std::vector<int> followSequence;
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            doc.getHMMSequence (centre, left, right, followSequence);
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            followCount = followSequence.size();
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    std::cout << "HMM: " << centre << " number of HMMs = " << followCount <<std::endl;
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            if (followCount >= 0) {
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        currId= firstId;
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        for (int jj= 0; jj < followCount; jj++) {
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            if (jj == (followCount - 1))
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                newId= arc[forwardList[bix]]->GetToId();
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            else
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		                newId= NewVertexId();
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            arcOne= CreateArc (followSequence[jj],
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project				arc[forwardList[bix]]->GetOutput(), currId, newId);
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            arcOne->AssignCentre (centre);
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            std::cout << "HMM phoneme: " << followSequence[jj] << " ";
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            currId= newId;
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        }
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        std::cout << " " << centre << std::endl;
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    }
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    bix++;
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		fix++;
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // arc[ii]->AssignInput (silenceId);
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ShiftOutputsToLeft ()
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    UpdateVertexCount (0);
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage();
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguageReverse();
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ReverseMarkArcs();
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MarkNodesByOutputAndClearArcs();
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ReverseMarkArcs ()
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii;
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++)
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() == WB_LABEL)
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            ReverseMarkOutput (arc[ii]->GetFromId(), startId, arc[ii]->GetOutput());
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ReverseMarkOutput (int currId, int initialId, int outId)
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int rix;
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rix= FindToIndex (currId);
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rix < 0)
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (rix < sortRevNum && arc[backwardList[rix]]->GetToId() == currId) {
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[backwardList[rix]]->GetOutput() != DISCARD_LABEL    //  not resolved yet
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         && arc[backwardList[rix]]->GetInput() >= 0) { // excludes word boundary
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (arc[backwardList[rix]]->GetOutput() == NONE_LABEL)
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[backwardList[rix]]->AssignOutput (outId);
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (outId != arc[backwardList[rix]]->GetOutput())
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[backwardList[rix]]->AssignOutput(DISCARD_LABEL);
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            ReverseMarkOutput (arc[backwardList[rix]]->GetFromId(), initialId, outId);
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix++;
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::MarkNodesByOutputAndClearArcs ()
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, currId, rix;
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int *nodeList= new int [numVertex];
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numVertex; ii++)
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        nodeList[ii]= NONE_LABEL;
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Associate outputs with destination node
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        currId= arc[ii]->GetToId();
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (currId >= 0) {
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (arc[ii]->GetInput() == WB_LABEL)
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                nodeList[currId]= DISCARD_LABEL;
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (nodeList[currId] != DISCARD_LABEL) {
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (nodeList[currId] == NONE_LABEL)
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    nodeList[currId]= arc[ii]->GetOutput();
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else if (nodeList[currId] != arc[ii]->GetOutput())
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    nodeList[currId]= DISCARD_LABEL;
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Now discard all arcs other than those emanating from unique assignments
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        currId= arc[ii]->GetFromId();
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (nodeList[currId] >= 0 && arc[ii]->GetOutput() >= 0) // unique ones
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignOutput(DISCARD_LABEL);
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Finally, special case for intra-word silence
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++) {
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (arc[ii]->GetOutput() >= 0 && arc[ii]->GetCentre() == intraId) {
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            currId= arc[ii]->GetToId();
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            std::cout << "Intra silence: " << currId << " " << arc[ii]->GetFromId() << std::endl;
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rix= FindFromIndex (currId);
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (rix < 0)
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                continue;
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                assert (arc[forwardList[rix]]->GetOutput() == DISCARD_LABEL);
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc[forwardList[rix]]->AssignOutput(arc[ii]->GetOutput());
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		rix++;
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    }
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignOutput(DISCARD_LABEL);
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    delete [] nodeList;
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::FinalProcessing (GRXMLDoc &doc)
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ExpandWordBoundaries (doc);
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    AddInitialFinalSilences (doc);
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ExpandWordBoundaries (GRXMLDoc &doc)
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, newId, count;
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc  *arcOne;
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count= numArc;
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < count; ii++) {
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        std::vector<int> modelSequence;
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        doc.getHMMSequence (silenceId, -1, -1, modelSequence);
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() == WB_LABEL) {
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            newId= NewVertexId();
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // (void) CreateArc (NONE_LABEL, NONE_LABEL, arc[ii]->GetFromId(), newId);
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // arcOne= CreateArc (modelSequence[0], NONE_LABEL, arc[ii]->GetFromId(), newId);
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arcOne= CreateArc (modelSequence[0], NONE_LABEL, arc[ii]->GetFromId(), newId);
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    arcOne->AssignCentre (silenceId);
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            (void) CreateArc (WB_LABEL, arc[ii]->GetOutput(), newId, arc[ii]->GetToId());
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // arc[ii]->AssignInput (DISCARD_LABEL);
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::AddInitialFinalSilences (GRXMLDoc &doc)
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, rix, newId, intId, count;
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc *arcOne;
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SortLanguage();
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    newId= NewVertexId();
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rix= FindFromIndex (startId);
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rix < 0)
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == startId) {
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        arc[forwardList[rix]]->AssignFromId (newId);
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix++;
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    std::vector<int> modelSequence;
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    doc.getHMMSequence (silenceId, -1, -1, modelSequence);
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    intId= NewVertexId();
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arcOne= CreateArc (modelSequence[0], INITIAL_LABEL, startId, intId);
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arcOne->AssignCentre (silenceId);
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    (void) CreateArc (WB_LABEL, NONE_LABEL, intId, newId);
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count= numArc;
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    newId= NewVertexId();
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < count; ii++) {
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() == TERMINAL_LABEL) {
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignInput (modelSequence[0]);
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignCentre (silenceId);
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignOutput (FINAL_LABEL);
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[ii]->AssignToId (newId);
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    (void) CreateArc (TERMINAL_LABEL, TERMINAL_LABEL, newId, newId);
4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
473