Home | History | Annotate | Download | only in grxmlcompile
      1 /* FILE:		sub_phon.cpp
      2  *  DATE MODIFIED:	31-Aug-07
      3  *  DESCRIPTION:	Part of the  SREC graph compiler project source files.
      4  *
      5  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
      6  *                                                                           *
      7  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
      8  *  you may not use this file except in compliance with the License.         *
      9  *                                                                           *
     10  *  You may obtain a copy of the License at                                  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0                           *
     12  *                                                                           *
     13  *  Unless required by applicable law or agreed to in writing, software      *
     14  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
     15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     16  *  See the License for the specific language governing permissions and      *
     17  *  limitations under the License.                                           *
     18  *                                                                           *
     19  *---------------------------------------------------------------------------*/
     20 
     21 #include <iostream>
     22 #include <sstream>
     23 #include <string>
     24 #include <assert.h>
     25 
     26 #define DEBUG           0
     27 
     28 #include "sub_grph.h"
     29 #include "grxmldoc.h"
     30 
     31 void SubGraph::ExpandPhonemes ( GRXMLDoc &doc )
     32 {
     33     int ii, wordId, phoneId, currId, newId, nextId, arcCount;
     34     Pronunciation pron;
     35     int pronCount;
     36     NUANArc *arcOne;
     37     std::string modelLabel, word;
     38 
     39     {
     40         std::stringstream ss;
     41         ss << SILENCE_CONTEXT;
     42         modelLabel= ss.str();
     43         silenceId = doc.addPhonemeToList(modelLabel);
     44     }
     45     {
     46         std::stringstream ss;
     47         ss << INTRA_SILENCE_CONTEXT;
     48         modelLabel= ss.str();
     49         intraId = doc.addPhonemeToList(modelLabel);
     50     }
     51     UpdateVertexCount (0);
     52     arcCount= numArc;
     53     for (ii= 0; ii < arcCount; ii++) {
     54         wordId= arc[ii]->GetInput();
     55         if (wordId >= 0) {
     56 	    doc.findLabel(wordId, word );
     57             if (IsSlot (word)) {
     58 	        // std::cout << "Found slot "<< word <<std::endl;
     59 	        newId= NewVertexId();
     60 	        arcOne= CreateArc (NONE_LABEL, NONE_LABEL, arc[ii]->GetFromId(), newId);
     61 		arcOne->AssignCentre (NONE_LABEL);
     62 	        nextId= NewVertexId();
     63 	        //  special case
     64 	        arcOne= CreateArc (-wordId, wordId, newId, nextId);
     65 		arcOne->AssignCentre (NONE_LABEL);
     66 	        // (void) CreateArc (-wordId, NONE_LABEL, arc[ii]->GetFromId(), newId);
     67 	        arcOne= CreateArc (WB_LABEL, NONE_LABEL, nextId, arc[ii]->GetToId());
     68 		arcOne->AssignCentre (NONE_LABEL);
     69 	        // (void) CreateArc (WB_LABEL, wordId, newId, arc[ii]->GetToId());
     70             }
     71             else {
     72 	        pron.clear();
     73 	        pron.lookup( *(doc.getVocabulary()), word );
     74 	        pronCount = pron.getPronCount();
     75 	        for (int jj= 0; jj < pronCount; jj++) {
     76 	            currId= arc[ii]->GetFromId();
     77 	            int modelCount = pron.getPhonemeCount(jj);
     78 	            for (int kk= 0; kk < modelCount; kk++) {
     79 	                newId= NewVertexId();
     80 	                pron.getPhoneme(jj, kk, modelLabel);
     81 	                //std::cout << "ExpandPhonemes adding "<< modelLabel <<std::endl;
     82 	                phoneId = doc.addPhonemeToList( modelLabel );
     83 	                arcOne= CreateArc (phoneId, NONE_LABEL, currId, newId);
     84                         if (phoneId == intraId)
     85 		            arcOne->AssignCentre (silenceId);
     86                         else
     87 		            arcOne->AssignCentre (phoneId);
     88 	                currId= newId;
     89 	            }
     90 	            arcOne= CreateArc (WB_LABEL, wordId, currId, arc[ii]->GetToId());
     91 		    arcOne->AssignCentre (NONE_LABEL);
     92 	        }
     93 	        //  End of loop
     94             }
     95 	    arc[ii]->AssignInput (DISCARD_LABEL);   //  Delete original arc
     96         }
     97     }
     98     RemoveDiscardedArcs ();
     99 
    100     for (ii= 0; ii < numArc; ii++) {
    101 	arc[ii]->AssignLeft (NONE_LABEL);
    102 	arc[ii]->AssignRight (NONE_LABEL);
    103     }
    104 
    105     SortLanguage ();
    106 
    107     return;
    108 }
    109 
    110 void SubGraph::AddLeftContexts ()
    111 {
    112     int ii, rix, currId, leftC;
    113 
    114     SortLanguage();
    115     SortLanguageReverse();
    116     for (ii= 0; ii < numArc; ii++) {
    117         if (arc[ii]->GetInput() >= 0) {
    118             currId= arc[ii]->GetFromId();
    119             rix= FindToIndex (currId);
    120             if (rix >= 0) {
    121                 leftC= arc[backwardList[rix]]->GetCentre();
    122                 arc[ii]->AssignLeft(leftC);
    123             }
    124             else if (currId != startId)
    125                 printf ("Shouldn't get here (L) %d\n", currId);
    126         }
    127         else
    128             arc[ii]->AssignLeft (NONE_LABEL);
    129     }
    130     return;
    131 }
    132 
    133 void SubGraph::AddRightContexts ()
    134 {
    135     int ii, rix, currId, rightC;
    136 
    137     SortLanguage();
    138     SortLanguageReverse();
    139     for (ii= 0; ii < numArc; ii++) {
    140         if (arc[ii]->GetInput() >= 0) {
    141             currId= arc[ii]->GetToId();
    142             rix= FindFromIndex (currId);
    143             if (rix >= 0) {
    144                 rightC= arc[forwardList[rix]]->GetCentre();
    145                 arc[ii]->AssignRight (rightC);
    146             }
    147             else
    148                 printf ("Shouldn't get here (R) %d\n", currId);
    149         }
    150         else
    151             arc[ii]->AssignRight (NONE_LABEL);
    152     }
    153     return;
    154 }
    155 
    156 void SubGraph::ExpandToHMMs ( GRXMLDoc &doc )
    157 {
    158     int ii, currId, newId, arcCount, left, right, centre;
    159     int modelCount;
    160     NUANArc *arcOne;
    161 
    162     UpdateVertexCount (0);
    163     arcCount= numArc;
    164     for (ii= 0; ii < arcCount; ii++) {
    165         std::vector<int> modelSequence;
    166 	if (arc[ii]->GetInput() >= 0) {      //  i.e. proper phoneme
    167             centre= arc[ii]->GetCentre();
    168 	    left= arc[ii]->GetLeft();
    169 	    right= arc[ii]->GetRight();
    170 #if DEBUG
    171             std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
    172 #endif
    173 	    doc.getHMMSequence (centre, left, right, modelSequence);
    174 	    modelCount = modelSequence.size();
    175 #if DEBUG
    176             std::cout << "HMM: " << centre << " number of HMMs = " << modelCount <<std::endl;
    177 #endif
    178 	    if (modelCount >= 0) {
    179 		currId= arc[ii]->GetFromId();
    180 		for (int jj= 0; jj < modelCount; jj++) {
    181                     if (jj == (modelCount - 1))
    182                         newId= arc[ii]->GetToId();
    183                     else
    184 		        newId= NewVertexId();
    185 		    arcOne= CreateArc (modelSequence[jj], NONE_LABEL, currId, newId);
    186 		    arcOne->AssignCentre (arc[ii]->GetInput());
    187 		    arcOne->AssignLeft (arc[ii]->GetLeft());
    188 		    arcOne->AssignRight (arc[ii]->GetRight());
    189 #if DEBUG
    190                     std::cout << "HMM phoneme: " << modelSequence[jj] << " ";
    191 #endif
    192 		    currId= newId;
    193 		}
    194 #if DEBUG
    195                 std::cout << " centre " << arc[ii]->GetInput() << std::endl;
    196 #endif
    197                 arc[ii]->AssignInput (DISCARD_LABEL);       //  Delete original arc
    198             }
    199         }
    200     }
    201     RemoveDiscardedArcs ();
    202 
    203     SortLanguage ();
    204 
    205     return;
    206 }
    207 
    208 void SubGraph::ExpandIntraWordSilence ( GRXMLDoc &doc )
    209 {
    210     int ii, fix, bix, firstId, newId, modelCount, followCount, currId, count;
    211     int left, centre, right;
    212     NUANArc *arcOne;
    213 
    214     SortLanguage();
    215     SortLanguageReverse();
    216 
    217 #if DEBUG
    218     std::cout << "Intra sil search " << intraId << std::endl;
    219 #endif
    220     count= numArc;
    221     for (ii= 0; ii < count; ii++) {
    222         if (arc[ii]->GetCentre() == intraId) {
    223 #if DEBUG
    224             std::cout << "Intra sil: " << arc[ii]->GetFromId() << " " << arc[ii]->GetToId() << std::endl;
    225 #endif
    226 
    227             fix= FindToIndex (arc[ii]->GetFromId());
    228             if (fix < 0)
    229                 return;
    230             while (fix < sortRevNum
    231              && arc[backwardList[fix]]->GetToId() == arc[ii]->GetFromId()) {
    232 		//  left triphone
    233                 newId= NewVertexId();
    234 		left= arc[backwardList[fix]]->GetLeft();
    235 		centre= arc[ii]->GetLeft();
    236 		right= arc[ii]->GetRight();
    237 #if DEBUG
    238                 std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
    239 #endif
    240                 std::vector<int> modelSequence;
    241 	        doc.getHMMSequence (centre, left, right, modelSequence);
    242 	        modelCount = modelSequence.size();
    243 #if DEBUG
    244                 std::cout << "HMM: " << centre << " number of HMMs = " << modelCount <<std::endl;
    245 #endif
    246 	        if (modelCount >= 0) {
    247 		    currId= arc[backwardList[fix]]->GetFromId();
    248 		    for (int jj= 0; jj < modelCount; jj++) {
    249 		        newId= NewVertexId();
    250 		        arcOne= CreateArc (modelSequence[jj],
    251 			    arc[backwardList[fix]]->GetOutput(), currId, newId);
    252 		        arcOne->AssignCentre (centre);
    253 #if DEBUG
    254                         std::cout << "HMM phoneme: " << modelSequence[jj] << " ";
    255 #endif
    256 		        currId= newId;
    257 		    }
    258 #if DEBUG
    259                     std::cout << " " << centre << std::endl;
    260 #endif
    261 		}
    262 		firstId= newId;
    263 
    264 		//  right block
    265                 bix= FindFromIndex (arc[ii]->GetToId());
    266                 if (bix < 0)
    267                     return;
    268                 while (bix < sortNum
    269                  && arc[forwardList[bix]]->GetFromId() == arc[ii]->GetToId()) {
    270                     fix++;
    271 		    //  right triphone
    272 		    left= arc[ii]->GetLeft();
    273 		    centre= arc[ii]->GetRight();
    274 		    right= arc[forwardList[bix]]->GetRight();
    275 
    276 #if DEBUG
    277                     std::cout << "HMM PIC:" << left <<" " << centre <<" " << right << std::endl;
    278 #endif
    279                     std::vector<int> followSequence;
    280 	            doc.getHMMSequence (centre, left, right, followSequence);
    281 	            followCount = followSequence.size();
    282 #if DEBUG
    283                     std::cout << "HMM: " << centre << " number of HMMs = " << followCount <<std::endl;
    284 #endif
    285 
    286 	            if (followCount >= 0) {
    287 		        currId= firstId;
    288 		        for (int jj= 0; jj < followCount; jj++) {
    289                             if (jj == (followCount - 1))
    290                                 newId= arc[forwardList[bix]]->GetToId();
    291                             else
    292 		                newId= NewVertexId();
    293 		            arcOne= CreateArc (followSequence[jj],
    294 				arc[forwardList[bix]]->GetOutput(), currId, newId);
    295 		            arcOne->AssignCentre (centre);
    296 #if DEBUG
    297                             std::cout << "HMM phoneme: " << followSequence[jj] << " ";
    298 #endif
    299 		            currId= newId;
    300 		        }
    301 #if DEBUG
    302                         std::cout << " " << centre << std::endl;
    303 #endif
    304 		    }
    305                     bix++;
    306                 }
    307 		fix++;
    308             }
    309             // arc[ii]->AssignInput (silenceId);
    310         }
    311     }
    312     return;
    313 }
    314 
    315 void SubGraph::ShiftOutputsToLeft ()
    316 {
    317     UpdateVertexCount (0);
    318     SortLanguage();
    319     SortLanguageReverse();
    320     ReverseMarkArcs();
    321     MarkNodesByOutputAndClearArcs();
    322     return;
    323 }
    324 
    325 void SubGraph::ReverseMarkArcs ()
    326 {
    327     int ii;
    328 
    329     for (ii= 0; ii < numArc; ii++)
    330         if (arc[ii]->GetInput() == WB_LABEL)
    331             ReverseMarkOutput (arc[ii]->GetFromId(), startId, arc[ii]->GetOutput());
    332     return;
    333 }
    334 
    335 void SubGraph::ReverseMarkOutput (int currId, int initialId, int outId)
    336 {
    337     int rix;
    338 
    339     rix= FindToIndex (currId);
    340     if (rix < 0)
    341         return;
    342     while (rix < sortRevNum && arc[backwardList[rix]]->GetToId() == currId) {
    343         if (arc[backwardList[rix]]->GetOutput() != DISCARD_LABEL    //  not resolved yet
    344          && arc[backwardList[rix]]->GetInput() >= 0) { // excludes word boundary
    345             if (arc[backwardList[rix]]->GetOutput() == NONE_LABEL)
    346                 arc[backwardList[rix]]->AssignOutput (outId);
    347             else if (outId != arc[backwardList[rix]]->GetOutput())
    348                 arc[backwardList[rix]]->AssignOutput(DISCARD_LABEL);
    349             ReverseMarkOutput (arc[backwardList[rix]]->GetFromId(), initialId, outId);
    350         }
    351         rix++;
    352     }
    353     return;
    354 }
    355 
    356 void SubGraph::MarkNodesByOutputAndClearArcs ()
    357 {
    358     int ii, currId, rix;
    359 
    360     int *nodeList= new int [numVertex];
    361     for (ii= 0; ii < numVertex; ii++)
    362         nodeList[ii]= NONE_LABEL;
    363 
    364     //  Associate outputs with destination node
    365     for (ii= 0; ii < numArc; ii++) {
    366         currId= arc[ii]->GetToId();
    367         if (currId >= 0) {
    368 	    if (arc[ii]->GetInput() == WB_LABEL)
    369                 nodeList[currId]= DISCARD_LABEL;
    370             else if (nodeList[currId] != DISCARD_LABEL) {
    371                 if (nodeList[currId] == NONE_LABEL)
    372                     nodeList[currId]= arc[ii]->GetOutput();
    373                 else if (nodeList[currId] != arc[ii]->GetOutput())
    374                     nodeList[currId]= DISCARD_LABEL;
    375             }
    376         }
    377     }
    378 
    379     //  Now discard all arcs other than those emanating from unique assignments
    380     for (ii= 0; ii < numArc; ii++) {
    381         currId= arc[ii]->GetFromId();
    382         if (nodeList[currId] >= 0 && arc[ii]->GetOutput() >= 0) // unique ones
    383             arc[ii]->AssignOutput(DISCARD_LABEL);
    384     }
    385 
    386     //  Finally, special case for intra-word silence
    387     for (ii= 0; ii < numArc; ii++) {
    388 	if (arc[ii]->GetOutput() >= 0 && arc[ii]->GetCentre() == intraId) {
    389             currId= arc[ii]->GetToId();
    390 #if DEBUG
    391             std::cout << "Intra silence: " << currId << " " << arc[ii]->GetFromId() << std::endl;
    392 #endif
    393             rix= FindFromIndex (currId);
    394             if (rix < 0)
    395                 continue;
    396             while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
    397                 assert (arc[forwardList[rix]]->GetOutput() == DISCARD_LABEL);
    398                 arc[forwardList[rix]]->AssignOutput(arc[ii]->GetOutput());
    399 		rix++;
    400 	    }
    401             arc[ii]->AssignOutput(DISCARD_LABEL);
    402         }
    403     }
    404 
    405     delete [] nodeList;
    406     return;
    407 }
    408 
    409 void SubGraph::FinalProcessing (GRXMLDoc &doc)
    410 {
    411     ExpandWordBoundaries (doc);
    412     AddInitialFinalSilences (doc);
    413     return;
    414 }
    415 
    416 void SubGraph::ExpandWordBoundaries (GRXMLDoc &doc)
    417 {
    418     int ii, newId, count;
    419     NUANArc  *arcOne;
    420 
    421     count= numArc;
    422     for (ii= 0; ii < count; ii++) {
    423         std::vector<int> modelSequence;
    424         doc.getHMMSequence (silenceId, -1, -1, modelSequence);
    425         if (arc[ii]->GetInput() == WB_LABEL) {
    426             newId= NewVertexId();
    427             // (void) CreateArc (NONE_LABEL, NONE_LABEL, arc[ii]->GetFromId(), newId);
    428             // arcOne= CreateArc (modelSequence[0], NONE_LABEL, arc[ii]->GetFromId(), newId);
    429             arcOne= CreateArc (modelSequence[0], NONE_LABEL, arc[ii]->GetFromId(), newId);
    430 	    arcOne->AssignCentre (silenceId);
    431             (void) CreateArc (WB_LABEL, arc[ii]->GetOutput(), newId, arc[ii]->GetToId());
    432             // arc[ii]->AssignInput (DISCARD_LABEL);
    433         }
    434     }
    435     return;
    436 }
    437 
    438 void SubGraph::AddInitialFinalSilences (GRXMLDoc &doc)
    439 {
    440     int ii, rix, newId, intId, count;
    441     NUANArc *arcOne;
    442 
    443     SortLanguage();
    444     newId= NewVertexId();
    445     rix= FindFromIndex (startId);
    446     if (rix < 0)
    447         return;
    448     while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == startId) {
    449         arc[forwardList[rix]]->AssignFromId (newId);
    450         rix++;
    451     }
    452     std::vector<int> modelSequence;
    453     doc.getHMMSequence (silenceId, -1, -1, modelSequence);
    454     intId= NewVertexId();
    455     arcOne= CreateArc (modelSequence[0], INITIAL_LABEL, startId, intId);
    456     arcOne->AssignCentre (silenceId);
    457     (void) CreateArc (WB_LABEL, NONE_LABEL, intId, newId);
    458 
    459     count= numArc;
    460     newId= NewVertexId();
    461     for (ii= 0; ii < count; ii++) {
    462         if (arc[ii]->GetInput() == TERMINAL_LABEL) {
    463             arc[ii]->AssignInput (modelSequence[0]);
    464             arc[ii]->AssignCentre (silenceId);
    465             arc[ii]->AssignOutput (FINAL_LABEL);
    466             arc[ii]->AssignToId (newId);
    467         }
    468     }
    469     (void) CreateArc (TERMINAL_LABEL, TERMINAL_LABEL, newId, newId);
    470 
    471     return;
    472 }
    473