• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ExpandPhonemes(GRXMLDoc & doc)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 
AddLeftContexts()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 
AddRightContexts()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 
ExpandToHMMs(GRXMLDoc & doc)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 
ExpandIntraWordSilence(GRXMLDoc & doc)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 
ShiftOutputsToLeft()315 void SubGraph::ShiftOutputsToLeft ()
316 {
317     UpdateVertexCount (0);
318     SortLanguage();
319     SortLanguageReverse();
320     ReverseMarkArcs();
321     MarkNodesByOutputAndClearArcs();
322     return;
323 }
324 
ReverseMarkArcs()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 
ReverseMarkOutput(int currId,int initialId,int outId)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 
MarkNodesByOutputAndClearArcs()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 
FinalProcessing(GRXMLDoc & doc)409 void SubGraph::FinalProcessing (GRXMLDoc &doc)
410 {
411     ExpandWordBoundaries (doc);
412     AddInitialFinalSilences (doc);
413     return;
414 }
415 
ExpandWordBoundaries(GRXMLDoc & doc)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 
AddInitialFinalSilences(GRXMLDoc & doc)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