Sophie

Sophie

distrib > Fedora > 14 > i386 > by-pkgid > e9280da098bff237733732ce38a34d57 > files > 157

pocketsphinx-devel-0.7-1.fc14.i686.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>PocketSphinx: src/libpocketsphinx/ngram_search.c Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.7.3 -->
<div id="top">
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">PocketSphinx&#160;<span id="projectnumber">0.6</span></div>
  </td>
 </tr>
 </tbody>
</table>
</div>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>Globals</span></a></li>
    </ul>
  </div>
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('ngram__search_8c.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<h1>src/libpocketsphinx/ngram_search.c</h1>  </div>
</div>
<div class="contents">
<a href="ngram__search_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */</span>
<a name="l00002"></a>00002 <span class="comment">/* ====================================================================</span>
<a name="l00003"></a>00003 <span class="comment"> * Copyright (c) 2008 Carnegie Mellon University.  All rights</span>
<a name="l00004"></a>00004 <span class="comment"> * reserved.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<a name="l00007"></a>00007 <span class="comment"> * modification, are permitted provided that the following conditions</span>
<a name="l00008"></a>00008 <span class="comment"> * are met:</span>
<a name="l00009"></a>00009 <span class="comment"> *</span>
<a name="l00010"></a>00010 <span class="comment"> * 1. Redistributions of source code must retain the above copyright</span>
<a name="l00011"></a>00011 <span class="comment"> *    notice, this list of conditions and the following disclaimer. </span>
<a name="l00012"></a>00012 <span class="comment"> *</span>
<a name="l00013"></a>00013 <span class="comment"> * 2. Redistributions in binary form must reproduce the above copyright</span>
<a name="l00014"></a>00014 <span class="comment"> *    notice, this list of conditions and the following disclaimer in</span>
<a name="l00015"></a>00015 <span class="comment"> *    the documentation and/or other materials provided with the</span>
<a name="l00016"></a>00016 <span class="comment"> *    distribution.</span>
<a name="l00017"></a>00017 <span class="comment"> *</span>
<a name="l00018"></a>00018 <span class="comment"> * This work was supported in part by funding from the Defense Advanced </span>
<a name="l00019"></a>00019 <span class="comment"> * Research Projects Agency and the National Science Foundation of the </span>
<a name="l00020"></a>00020 <span class="comment"> * United States of America, and the CMU Sphinx Speech Consortium.</span>
<a name="l00021"></a>00021 <span class="comment"> *</span>
<a name="l00022"></a>00022 <span class="comment"> * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS&#39;&#39; AND </span>
<a name="l00023"></a>00023 <span class="comment"> * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, </span>
<a name="l00024"></a>00024 <span class="comment"> * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR</span>
<a name="l00025"></a>00025 <span class="comment"> * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY</span>
<a name="l00026"></a>00026 <span class="comment"> * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
<a name="l00027"></a>00027 <span class="comment"> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT </span>
<a name="l00028"></a>00028 <span class="comment"> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, </span>
<a name="l00029"></a>00029 <span class="comment"> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY </span>
<a name="l00030"></a>00030 <span class="comment"> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT </span>
<a name="l00031"></a>00031 <span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE </span>
<a name="l00032"></a>00032 <span class="comment"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<a name="l00033"></a>00033 <span class="comment"> *</span>
<a name="l00034"></a>00034 <span class="comment"> * ====================================================================</span>
<a name="l00035"></a>00035 <span class="comment"> *</span>
<a name="l00036"></a>00036 <span class="comment"> */</span>
<a name="l00037"></a>00037 
<a name="l00042"></a>00042 <span class="comment">/* System headers. */</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00044"></a>00044 <span class="preprocessor">#include &lt;assert.h&gt;</span>
<a name="l00045"></a>00045 
<a name="l00046"></a>00046 <span class="comment">/* SphinxBase headers. */</span>
<a name="l00047"></a>00047 <span class="preprocessor">#include &lt;sphinxbase/ckd_alloc.h&gt;</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include &lt;sphinxbase/listelem_alloc.h&gt;</span>
<a name="l00049"></a>00049 <span class="preprocessor">#include &lt;sphinxbase/err.h&gt;</span>
<a name="l00050"></a>00050 
<a name="l00051"></a>00051 <span class="comment">/* Local headers. */</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include &quot;<a class="code" href="pocketsphinx__internal_8h.html" title="Internal implementation of PocketSphinx decoder.">pocketsphinx_internal.h</a>&quot;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include &quot;<a class="code" href="ps__lattice__internal_8h.html" title="Word graph search implementation.">ps_lattice_internal.h</a>&quot;</span>
<a name="l00054"></a>00054 <span class="preprocessor">#include &quot;<a class="code" href="ngram__search_8h.html" title="N-Gram based multi-pass search (&amp;quot;FBS&amp;quot;)">ngram_search.h</a>&quot;</span>
<a name="l00055"></a>00055 <span class="preprocessor">#include &quot;<a class="code" href="ngram__search__fwdtree_8h.html" title="Lexicon tree based Viterbi search.">ngram_search_fwdtree.h</a>&quot;</span>
<a name="l00056"></a>00056 <span class="preprocessor">#include &quot;<a class="code" href="ngram__search__fwdflat_8h.html" title="Flat lexicon based Viterbi search.">ngram_search_fwdflat.h</a>&quot;</span>
<a name="l00057"></a>00057 
<a name="l00058"></a>00058 <span class="keyword">static</span> <span class="keywordtype">int</span> ngram_search_start(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search);
<a name="l00059"></a>00059 <span class="keyword">static</span> <span class="keywordtype">int</span> ngram_search_step(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, <span class="keywordtype">int</span> frame_idx);
<a name="l00060"></a>00060 <span class="keyword">static</span> <span class="keywordtype">int</span> ngram_search_finish(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search);
<a name="l00061"></a>00061 <span class="keyword">static</span> <span class="keywordtype">int</span> ngram_search_reinit(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict, <a class="code" href="structdict2pid__t.html" title="Building composite triphone (as well as word internal triphones) with the dictionary.">dict2pid_t</a> *d2p);
<a name="l00062"></a>00062 <span class="keyword">static</span> <span class="keywordtype">char</span> <span class="keyword">const</span> *ngram_search_hyp(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, int32 *out_score);
<a name="l00063"></a>00063 <span class="keyword">static</span> int32 ngram_search_prob(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search);
<a name="l00064"></a>00064 <span class="keyword">static</span> <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *ngram_search_seg_iter(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, int32 *out_score);
<a name="l00065"></a>00065 
<a name="l00066"></a>00066 <span class="keyword">static</span> <a class="code" href="structps__searchfuncs__s.html" title="V-table for search algorithm.">ps_searchfuncs_t</a> ngram_funcs = {
<a name="l00067"></a>00067     <span class="comment">/* name: */</span>   <span class="stringliteral">&quot;ngram&quot;</span>,
<a name="l00068"></a>00068     <span class="comment">/* start: */</span>  ngram_search_start,
<a name="l00069"></a>00069     <span class="comment">/* step: */</span>   ngram_search_step,
<a name="l00070"></a>00070     <span class="comment">/* finish: */</span> ngram_search_finish,
<a name="l00071"></a>00071     <span class="comment">/* reinit: */</span> ngram_search_reinit,
<a name="l00072"></a>00072     <span class="comment">/* free: */</span>   <a class="code" href="ngram__search_8c.html#aeaf140dc2bbeaa5c274f73480b5328f3" title="Finalize the N-Gram search module.">ngram_search_free</a>,
<a name="l00073"></a>00073     <span class="comment">/* lattice: */</span>  <a class="code" href="ngram__search_8c.html#ac30e7dec4bbfeee9f5163abf4bbd1014" title="Construct a word lattice from the current hypothesis.">ngram_search_lattice</a>,
<a name="l00074"></a>00074     <span class="comment">/* hyp: */</span>      ngram_search_hyp,
<a name="l00075"></a>00075     <span class="comment">/* prob: */</span>     ngram_search_prob,
<a name="l00076"></a>00076     <span class="comment">/* seg_iter: */</span> ngram_search_seg_iter,
<a name="l00077"></a>00077 };
<a name="l00078"></a>00078 
<a name="l00079"></a>00079 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00080"></a>00080 ngram_search_update_widmap(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs)
<a name="l00081"></a>00081 {
<a name="l00082"></a>00082     <span class="keyword">const</span> <span class="keywordtype">char</span> **words;
<a name="l00083"></a>00083     int32 i, n_words;
<a name="l00084"></a>00084 
<a name="l00085"></a>00085     <span class="comment">/* It&#39;s okay to include fillers since they won&#39;t be in the LM */</span>
<a name="l00086"></a>00086     n_words = ps_search_n_words(ngs);
<a name="l00087"></a>00087     words = ckd_calloc(n_words, <span class="keyword">sizeof</span>(*words));
<a name="l00088"></a>00088     <span class="comment">/* This will include alternates, again, that&#39;s okay since they aren&#39;t in the LM */</span>
<a name="l00089"></a>00089     <span class="keywordflow">for</span> (i = 0; i &lt; n_words; ++i)
<a name="l00090"></a>00090         words[i] = (<span class="keyword">const</span> <span class="keywordtype">char</span> *)dict_wordstr(ps_search_dict(ngs), i);
<a name="l00091"></a>00091     ngram_model_set_map_words(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>, words, n_words);
<a name="l00092"></a>00092     ckd_free(words);
<a name="l00093"></a>00093 }
<a name="l00094"></a>00094 
<a name="l00095"></a>00095 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00096"></a>00096 ngram_search_calc_beams(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs)
<a name="l00097"></a>00097 {
<a name="l00098"></a>00098     cmd_ln_t *config;
<a name="l00099"></a>00099     <a class="code" href="structacmod__s.html" title="Acoustic model structure.">acmod_t</a> *acmod;
<a name="l00100"></a>00100 
<a name="l00101"></a>00101     config = ps_search_config(ngs);
<a name="l00102"></a>00102     acmod = ps_search_acmod(ngs);
<a name="l00103"></a>00103 
<a name="l00104"></a>00104     <span class="comment">/* Log beam widths. */</span>
<a name="l00105"></a>00105     ngs-&gt;beam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-beam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00106"></a>00106     ngs-&gt;wbeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-wbeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00107"></a>00107     ngs-&gt;pbeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-pbeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00108"></a>00108     ngs-&gt;lpbeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-lpbeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00109"></a>00109     ngs-&gt;lponlybeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-lponlybeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00110"></a>00110     ngs-&gt;fwdflatbeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-fwdflatbeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00111"></a>00111     ngs-&gt;fwdflatwbeam = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float64_r(config, <span class="stringliteral">&quot;-fwdflatwbeam&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00112"></a>00112 
<a name="l00113"></a>00113     <span class="comment">/* Absolute pruning parameters. */</span>
<a name="l00114"></a>00114     ngs-&gt;maxwpf = cmd_ln_int32_r(config, <span class="stringliteral">&quot;-maxwpf&quot;</span>);
<a name="l00115"></a>00115     ngs-&gt;maxhmmpf = cmd_ln_int32_r(config, <span class="stringliteral">&quot;-maxhmmpf&quot;</span>);
<a name="l00116"></a>00116 
<a name="l00117"></a>00117     <span class="comment">/* Various penalties which may or may not be useful. */</span>
<a name="l00118"></a>00118     ngs-&gt;wip = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float32_r(config, <span class="stringliteral">&quot;-wip&quot;</span>)) &gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00119"></a>00119     ngs-&gt;nwpen = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float32_r(config, <span class="stringliteral">&quot;-nwpen&quot;</span>)) &gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00120"></a>00120     ngs-&gt;pip = logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float32_r(config, <span class="stringliteral">&quot;-pip&quot;</span>)) &gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00121"></a>00121     ngs-&gt;silpen = ngs-&gt;pip
<a name="l00122"></a>00122         + (logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float32_r(config, <span class="stringliteral">&quot;-silprob&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>);
<a name="l00123"></a>00123     ngs-&gt;fillpen = ngs-&gt;pip
<a name="l00124"></a>00124         + (logmath_log(acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, cmd_ln_float32_r(config, <span class="stringliteral">&quot;-fillprob&quot;</span>))&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>);
<a name="l00125"></a>00125 
<a name="l00126"></a>00126     <span class="comment">/* Language weight ratios for fwdflat and bestpath search. */</span>
<a name="l00127"></a>00127     ngs-&gt;fwdflat_fwdtree_lw_ratio =
<a name="l00128"></a>00128         cmd_ln_float32_r(config, <span class="stringliteral">&quot;-fwdflatlw&quot;</span>)
<a name="l00129"></a>00129         / cmd_ln_float32_r(config, <span class="stringliteral">&quot;-lw&quot;</span>);
<a name="l00130"></a>00130     ngs-&gt;bestpath_fwdtree_lw_ratio =
<a name="l00131"></a>00131         cmd_ln_float32_r(config, <span class="stringliteral">&quot;-bestpathlw&quot;</span>)
<a name="l00132"></a>00132         / cmd_ln_float32_r(config, <span class="stringliteral">&quot;-lw&quot;</span>);
<a name="l00133"></a>00133 
<a name="l00134"></a>00134     <span class="comment">/* Acoustic score scale for posterior probabilities. */</span>
<a name="l00135"></a>00135     ngs-&gt;<a class="code" href="structngram__search__s.html#a1e3d4b67e4b11c6c11ebe16552d53d2d" title="Acoustic score scale for posterior probabilities.">ascale</a> = 1.0 / cmd_ln_float32_r(config, <span class="stringliteral">&quot;-ascale&quot;</span>);
<a name="l00136"></a>00136 }
<a name="l00137"></a>00137 
<a name="l00138"></a>00138 <a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *
<a name="l00139"></a><a class="code" href="ngram__search_8h.html#afa0dcbb86340083bce1412c9309742bc">00139</a> <a class="code" href="ngram__search_8c.html#afa0dcbb86340083bce1412c9309742bc" title="Initialize the N-Gram search module.">ngram_search_init</a>(cmd_ln_t *config,
<a name="l00140"></a>00140                   <a class="code" href="structacmod__s.html" title="Acoustic model structure.">acmod_t</a> *acmod,
<a name="l00141"></a>00141                   <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict,
<a name="l00142"></a>00142                   <a class="code" href="structdict2pid__t.html" title="Building composite triphone (as well as word internal triphones) with the dictionary.">dict2pid_t</a> *d2p)
<a name="l00143"></a>00143 {
<a name="l00144"></a>00144     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs;
<a name="l00145"></a>00145     <span class="keyword">const</span> <span class="keywordtype">char</span> *path;
<a name="l00146"></a>00146 
<a name="l00147"></a>00147     ngs = ckd_calloc(1, <span class="keyword">sizeof</span>(*ngs));
<a name="l00148"></a>00148     ps_search_init(&amp;ngs-&gt;base, &amp;ngram_funcs, config, acmod, dict, d2p);
<a name="l00149"></a>00149     ngs-&gt;<a class="code" href="structngram__search__s.html#acfbdd34e3dadbaa384818402f1dd59bf" title="HMM context.">hmmctx</a> = hmm_context_init(bin_mdef_n_emit_state(acmod-&gt;<a class="code" href="structacmod__s.html#a351548ff5547c29b4a684e10434a51dd" title="Model definition.">mdef</a>),
<a name="l00150"></a>00150                                    acmod-&gt;<a class="code" href="structacmod__s.html#aaa3982184a49f0d61e397ba89f486259" title="Transition matrices.">tmat</a>-&gt;<a class="code" href="structtmat__t.html#a9f518c96b30dab9efdb69bd779a7b5bf" title="The transition matrices; kept in the same scale as acoustic scores; tp[tmatid][from-state][to-state]...">tp</a>, NULL, acmod-&gt;<a class="code" href="structacmod__s.html#a351548ff5547c29b4a684e10434a51dd" title="Model definition.">mdef</a>-&gt;<a class="code" href="structbin__mdef__s.html#acb58480658812de7a357dcbd25ad7b41" title="Unique senone sequences (2D array built at load time)">sseq</a>);
<a name="l00151"></a>00151     <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#acfbdd34e3dadbaa384818402f1dd59bf" title="HMM context.">hmmctx</a> == NULL) {
<a name="l00152"></a>00152         ps_search_free(ps_search_base(ngs));
<a name="l00153"></a>00153         <span class="keywordflow">return</span> NULL;
<a name="l00154"></a>00154     }
<a name="l00155"></a>00155     ngs-&gt;<a class="code" href="structngram__search__s.html#abe9fe60f6e48b9a6e3d41856bb1dc109" title="For chan_t.">chan_alloc</a> = listelem_alloc_init(<span class="keyword">sizeof</span>(<a class="code" href="structchan__s.html" title="Lexical tree node data type.">chan_t</a>));
<a name="l00156"></a>00156     ngs-&gt;<a class="code" href="structngram__search__s.html#a576470858bfa44c671f0e677902ab424" title="For root_chan_t.">root_chan_alloc</a> = listelem_alloc_init(<span class="keyword">sizeof</span>(<a class="code" href="structroot__chan__s.html" title="Lexical tree node data type for the first phone (root) of each dynamic HMM tree structure.">root_chan_t</a>));
<a name="l00157"></a>00157     ngs-&gt;<a class="code" href="structngram__search__s.html#a21600dc2e23744f0be9c64a4db8d7e50" title="For latnode_t.">latnode_alloc</a> = listelem_alloc_init(<span class="keyword">sizeof</span>(<a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a>));
<a name="l00158"></a>00158 
<a name="l00159"></a>00159     <span class="comment">/* Calculate various beam widths and such. */</span>
<a name="l00160"></a>00160     ngram_search_calc_beams(ngs);
<a name="l00161"></a>00161 
<a name="l00162"></a>00162     <span class="comment">/* Allocate a billion different tables for stuff. */</span>
<a name="l00163"></a>00163     ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a> = ckd_calloc(<a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict),
<a name="l00164"></a>00164                                 <span class="keyword">sizeof</span>(*ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>));
<a name="l00165"></a>00165     ngs-&gt;word_lat_idx = ckd_calloc(<a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict),
<a name="l00166"></a>00166                                    <span class="keyword">sizeof</span>(*ngs-&gt;word_lat_idx));
<a name="l00167"></a>00167     ngs-&gt;<a class="code" href="structngram__search__s.html#aeb4c98851bf9b239ca607ca59f59ff4c" title="array of active flags for all words.">word_active</a> = bitvec_alloc(<a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict));
<a name="l00168"></a>00168     ngs-&gt;last_ltrans = ckd_calloc(<a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict),
<a name="l00169"></a>00169                                   <span class="keyword">sizeof</span>(*ngs-&gt;last_ltrans));
<a name="l00170"></a>00170 
<a name="l00171"></a>00171     <span class="comment">/* FIXME: All these structures need to be made dynamic with</span>
<a name="l00172"></a>00172 <span class="comment">     * garbage collection. */</span>
<a name="l00173"></a>00173     ngs-&gt;bp_table_size = cmd_ln_int32_r(config, <span class="stringliteral">&quot;-latsize&quot;</span>);
<a name="l00174"></a>00174     ngs-&gt;bp_table = ckd_calloc(ngs-&gt;bp_table_size,
<a name="l00175"></a>00175                                <span class="keyword">sizeof</span>(*ngs-&gt;bp_table));
<a name="l00176"></a>00176     <span class="comment">/* FIXME: This thing is frickin&#39; huge. */</span>
<a name="l00177"></a>00177     ngs-&gt;bscore_stack_size = ngs-&gt;bp_table_size * 20;
<a name="l00178"></a>00178     ngs-&gt;bscore_stack = ckd_calloc(ngs-&gt;bscore_stack_size,
<a name="l00179"></a>00179                                    <span class="keyword">sizeof</span>(*ngs-&gt;bscore_stack));
<a name="l00180"></a>00180     ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a> = 256;
<a name="l00181"></a>00181     ngs-&gt;bp_table_idx = ckd_calloc(ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a> + 1,
<a name="l00182"></a>00182                                    <span class="keyword">sizeof</span>(*ngs-&gt;bp_table_idx));
<a name="l00183"></a>00183     ++ngs-&gt;bp_table_idx; <span class="comment">/* Make bptableidx[-1] valid */</span>
<a name="l00184"></a>00184 
<a name="l00185"></a>00185     <span class="comment">/* Allocate active word list array */</span>
<a name="l00186"></a>00186     ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a> = ckd_calloc_2d(2, <a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict),
<a name="l00187"></a>00187                                           <span class="keyword">sizeof</span>(**ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a>));
<a name="l00188"></a>00188 
<a name="l00189"></a>00189     <span class="comment">/* Load language model(s) */</span>
<a name="l00190"></a>00190     <span class="keywordflow">if</span> ((path = cmd_ln_str_r(config, <span class="stringliteral">&quot;-lmctl&quot;</span>))) {
<a name="l00191"></a>00191         ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> = ngram_model_set_read(config, path, acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>);
<a name="l00192"></a>00192         <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> == NULL) {
<a name="l00193"></a>00193             E_ERROR(<span class="stringliteral">&quot;Failed to read language model control file: %s\n&quot;</span>,
<a name="l00194"></a>00194                     path);
<a name="l00195"></a>00195             <span class="keywordflow">goto</span> error_out;
<a name="l00196"></a>00196         }
<a name="l00197"></a>00197         <span class="comment">/* Set the default language model if needed. */</span>
<a name="l00198"></a>00198         <span class="keywordflow">if</span> ((path = cmd_ln_str_r(config, <span class="stringliteral">&quot;-lmname&quot;</span>))) {
<a name="l00199"></a>00199             ngram_model_set_select(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>, path);
<a name="l00200"></a>00200         }
<a name="l00201"></a>00201     }
<a name="l00202"></a>00202     <span class="keywordflow">else</span> <span class="keywordflow">if</span> ((path = cmd_ln_str_r(config, <span class="stringliteral">&quot;-lm&quot;</span>))) {
<a name="l00203"></a>00203         <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *name = <span class="stringliteral">&quot;default&quot;</span>;
<a name="l00204"></a>00204         ngram_model_t *lm;
<a name="l00205"></a>00205 
<a name="l00206"></a>00206         lm = ngram_model_read(config, path, NGRAM_AUTO, acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>);
<a name="l00207"></a>00207         <span class="keywordflow">if</span> (lm == NULL) {
<a name="l00208"></a>00208             E_ERROR(<span class="stringliteral">&quot;Failed to read language model file: %s\n&quot;</span>, path);
<a name="l00209"></a>00209             <span class="keywordflow">goto</span> error_out;
<a name="l00210"></a>00210         }
<a name="l00211"></a>00211         ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> = ngram_model_set_init(config,
<a name="l00212"></a>00212                                           &amp;lm, (<span class="keywordtype">char</span> **)&amp;name,
<a name="l00213"></a>00213                                           NULL, 1);
<a name="l00214"></a>00214         <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> == NULL) {
<a name="l00215"></a>00215             E_ERROR(<span class="stringliteral">&quot;Failed to initialize language model set\n&quot;</span>);
<a name="l00216"></a>00216             <span class="keywordflow">goto</span> error_out;
<a name="l00217"></a>00217         }
<a name="l00218"></a>00218     }
<a name="l00219"></a>00219     <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> != NULL
<a name="l00220"></a>00220         &amp;&amp; ngram_wid(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>, S3_FINISH_WORD) == ngram_unknown_wid(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>)) {
<a name="l00221"></a>00221         E_ERROR(<span class="stringliteral">&quot;Language model/set does not contain &lt;/s&gt;, recognition will fail\n&quot;</span>);
<a name="l00222"></a>00222         <span class="keywordflow">goto</span> error_out;
<a name="l00223"></a>00223     }
<a name="l00224"></a>00224 
<a name="l00225"></a>00225     <span class="comment">/* Create word mappings. */</span>
<a name="l00226"></a>00226     ngram_search_update_widmap(ngs);
<a name="l00227"></a>00227 
<a name="l00228"></a>00228     <span class="comment">/* Initialize fwdtree, fwdflat, bestpath modules if necessary. */</span>
<a name="l00229"></a>00229     <span class="keywordflow">if</span> (cmd_ln_boolean_r(config, <span class="stringliteral">&quot;-fwdtree&quot;</span>)) {
<a name="l00230"></a>00230         <a class="code" href="ngram__search__fwdtree_8c.html#a72c89a2a1f189495abee00e1853cddcc" title="Initialize N-Gram search for fwdtree decoding.">ngram_fwdtree_init</a>(ngs);
<a name="l00231"></a>00231         ngs-&gt;fwdtree = TRUE;
<a name="l00232"></a>00232         ngs-&gt;fwdtree_perf.name = <span class="stringliteral">&quot;fwdtree&quot;</span>;
<a name="l00233"></a>00233         ptmr_init(&amp;ngs-&gt;fwdtree_perf);
<a name="l00234"></a>00234     }
<a name="l00235"></a>00235     <span class="keywordflow">if</span> (cmd_ln_boolean_r(config, <span class="stringliteral">&quot;-fwdflat&quot;</span>)) {
<a name="l00236"></a>00236         <a class="code" href="ngram__search__fwdflat_8c.html#ad4b8ebd904c77f8a28f59cd5ca2c8307" title="Initialize N-Gram search for fwdflat decoding.">ngram_fwdflat_init</a>(ngs);
<a name="l00237"></a>00237         ngs-&gt;fwdflat = TRUE;
<a name="l00238"></a>00238         ngs-&gt;fwdflat_perf.name = <span class="stringliteral">&quot;fwdflat&quot;</span>;
<a name="l00239"></a>00239         ptmr_init(&amp;ngs-&gt;fwdflat_perf);
<a name="l00240"></a>00240     }
<a name="l00241"></a>00241     <span class="keywordflow">if</span> (cmd_ln_boolean_r(config, <span class="stringliteral">&quot;-bestpath&quot;</span>)) {
<a name="l00242"></a>00242         ngs-&gt;bestpath = TRUE;
<a name="l00243"></a>00243         ngs-&gt;bestpath_perf.name = <span class="stringliteral">&quot;bestpath&quot;</span>;
<a name="l00244"></a>00244         ptmr_init(&amp;ngs-&gt;bestpath_perf);
<a name="l00245"></a>00245     }
<a name="l00246"></a>00246 
<a name="l00247"></a>00247     <span class="keywordflow">return</span> (<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *)ngs;
<a name="l00248"></a>00248 
<a name="l00249"></a>00249 error_out:
<a name="l00250"></a>00250     <a class="code" href="ngram__search_8c.html#aeaf140dc2bbeaa5c274f73480b5328f3" title="Finalize the N-Gram search module.">ngram_search_free</a>((<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *)ngs);
<a name="l00251"></a>00251     <span class="keywordflow">return</span> NULL;
<a name="l00252"></a>00252 }
<a name="l00253"></a>00253 
<a name="l00254"></a>00254 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00255"></a>00255 ngram_search_reinit(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict, <a class="code" href="structdict2pid__t.html" title="Building composite triphone (as well as word internal triphones) with the dictionary.">dict2pid_t</a> *d2p)
<a name="l00256"></a>00256 {
<a name="l00257"></a>00257     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00258"></a>00258     <span class="keywordtype">int</span> old_n_words;
<a name="l00259"></a>00259     <span class="keywordtype">int</span> rv = 0;
<a name="l00260"></a>00260 
<a name="l00261"></a>00261     <span class="comment">/* Update the number of words. */</span>
<a name="l00262"></a>00262     old_n_words = search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a>;
<a name="l00263"></a>00263     <span class="keywordflow">if</span> (old_n_words != <a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict)) {
<a name="l00264"></a>00264         search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a> = <a class="code" href="dict_8h.html#a361b948b42f9cfdf5c7fa9dfc8a71a94" title="Packaged macro access to dictionary members.">dict_size</a>(dict);
<a name="l00265"></a>00265         <span class="comment">/* Reallocate these temporary arrays. */</span>
<a name="l00266"></a>00266         ckd_free(ngs-&gt;word_lat_idx);
<a name="l00267"></a>00267         ckd_free(ngs-&gt;<a class="code" href="structngram__search__s.html#aeb4c98851bf9b239ca607ca59f59ff4c" title="array of active flags for all words.">word_active</a>);
<a name="l00268"></a>00268         ckd_free(ngs-&gt;last_ltrans);
<a name="l00269"></a>00269         ckd_free_2d(ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a>);
<a name="l00270"></a>00270         ngs-&gt;word_lat_idx = ckd_calloc(search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a>, <span class="keyword">sizeof</span>(*ngs-&gt;word_lat_idx));
<a name="l00271"></a>00271         ngs-&gt;<a class="code" href="structngram__search__s.html#aeb4c98851bf9b239ca607ca59f59ff4c" title="array of active flags for all words.">word_active</a> = bitvec_alloc(search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a>);
<a name="l00272"></a>00272         ngs-&gt;last_ltrans = ckd_calloc(search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a>, <span class="keyword">sizeof</span>(*ngs-&gt;last_ltrans));
<a name="l00273"></a>00273         ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a>
<a name="l00274"></a>00274             = ckd_calloc_2d(2, search-&gt;<a class="code" href="structps__search__s.html#ad4d98deb905bd664ec44313ea0065b1a" title="Number of words known to search (may be less than in the dictionary)">n_words</a>,
<a name="l00275"></a>00275                             <span class="keyword">sizeof</span>(**ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a>));
<a name="l00276"></a>00276     }
<a name="l00277"></a>00277 
<a name="l00278"></a>00278     <span class="comment">/* Free old dict2pid, dict */</span>
<a name="l00279"></a>00279     ps_search_base_reinit(search, dict, d2p);
<a name="l00280"></a>00280     
<a name="l00281"></a>00281     <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a> == NULL)
<a name="l00282"></a>00282         <span class="keywordflow">return</span>;
<a name="l00283"></a>00283 
<a name="l00284"></a>00284     <span class="comment">/* Update beam widths. */</span>
<a name="l00285"></a>00285     ngram_search_calc_beams(ngs);
<a name="l00286"></a>00286 
<a name="l00287"></a>00287     <span class="comment">/* Update word mappings. */</span>
<a name="l00288"></a>00288     ngram_search_update_widmap(ngs);
<a name="l00289"></a>00289 
<a name="l00290"></a>00290     <span class="comment">/* Now rebuild lextrees. */</span>
<a name="l00291"></a>00291     <span class="keywordflow">if</span> (ngs-&gt;fwdtree) {
<a name="l00292"></a>00292         <span class="keywordflow">if</span> ((rv = <a class="code" href="ngram__search__fwdtree_8c.html#aa53827b47025d4e7a63f3ddce763d84e" title="Rebuild search structures for updated language models.">ngram_fwdtree_reinit</a>(ngs)) &lt; 0)
<a name="l00293"></a>00293             <span class="keywordflow">return</span> rv;
<a name="l00294"></a>00294     }
<a name="l00295"></a>00295     <span class="keywordflow">if</span> (ngs-&gt;fwdflat) {
<a name="l00296"></a>00296         <span class="keywordflow">if</span> ((rv = <a class="code" href="ngram__search__fwdflat_8c.html#aa4879c06ddbc455a6f355084a9c574b4" title="Rebuild search structures for updated language models.">ngram_fwdflat_reinit</a>(ngs)) &lt; 0)
<a name="l00297"></a>00297             <span class="keywordflow">return</span> rv;
<a name="l00298"></a>00298     }
<a name="l00299"></a>00299 
<a name="l00300"></a>00300     <span class="keywordflow">return</span> rv;
<a name="l00301"></a>00301 }
<a name="l00302"></a>00302 
<a name="l00303"></a>00303 <span class="keywordtype">void</span>
<a name="l00304"></a><a class="code" href="ngram__search_8h.html#a9bafaa4af5a9a4f9e76a8daf54ac4a11">00304</a> <a class="code" href="ngram__search_8c.html#aeaf140dc2bbeaa5c274f73480b5328f3" title="Finalize the N-Gram search module.">ngram_search_free</a>(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l00305"></a>00305 {
<a name="l00306"></a>00306     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00307"></a>00307 
<a name="l00308"></a>00308     ps_search_deinit(search);
<a name="l00309"></a>00309     <span class="keywordflow">if</span> (ngs-&gt;fwdtree)
<a name="l00310"></a>00310         <a class="code" href="ngram__search__fwdtree_8c.html#a0e0e0436b30e1074114e1d37991c5d6b" title="Release memory associated with fwdtree decoding.">ngram_fwdtree_deinit</a>(ngs);
<a name="l00311"></a>00311     <span class="keywordflow">if</span> (ngs-&gt;fwdflat)
<a name="l00312"></a>00312         <a class="code" href="ngram__search__fwdflat_8c.html#a8faf467f90162a7273b23304fc6e8586" title="Release memory associated with fwdflat decoding.">ngram_fwdflat_deinit</a>(ngs);
<a name="l00313"></a>00313     <span class="keywordflow">if</span> (ngs-&gt;bestpath) {
<a name="l00314"></a>00314         <span class="keywordtype">double</span> n_speech = (double)ngs-&gt;n_tot_frame
<a name="l00315"></a>00315             / cmd_ln_int32_r(ps_search_config(ngs), <span class="stringliteral">&quot;-frate&quot;</span>);
<a name="l00316"></a>00316 
<a name="l00317"></a>00317         E_INFO(<span class="stringliteral">&quot;TOTAL bestpath %.2f CPU %.3f xRT\n&quot;</span>,
<a name="l00318"></a>00318                ngs-&gt;bestpath_perf.t_tot_cpu,
<a name="l00319"></a>00319                ngs-&gt;bestpath_perf.t_tot_cpu / n_speech);
<a name="l00320"></a>00320         E_INFO(<span class="stringliteral">&quot;TOTAL bestpath %.2f wall %.3f xRT\n&quot;</span>,
<a name="l00321"></a>00321                ngs-&gt;bestpath_perf.t_tot_elapsed,
<a name="l00322"></a>00322                ngs-&gt;bestpath_perf.t_tot_elapsed / n_speech);
<a name="l00323"></a>00323     }
<a name="l00324"></a>00324 
<a name="l00325"></a>00325     hmm_context_free(ngs-&gt;<a class="code" href="structngram__search__s.html#acfbdd34e3dadbaa384818402f1dd59bf" title="HMM context.">hmmctx</a>);
<a name="l00326"></a>00326     listelem_alloc_free(ngs-&gt;<a class="code" href="structngram__search__s.html#abe9fe60f6e48b9a6e3d41856bb1dc109" title="For chan_t.">chan_alloc</a>);
<a name="l00327"></a>00327     listelem_alloc_free(ngs-&gt;<a class="code" href="structngram__search__s.html#a576470858bfa44c671f0e677902ab424" title="For root_chan_t.">root_chan_alloc</a>);
<a name="l00328"></a>00328     listelem_alloc_free(ngs-&gt;<a class="code" href="structngram__search__s.html#a21600dc2e23744f0be9c64a4db8d7e50" title="For latnode_t.">latnode_alloc</a>);
<a name="l00329"></a>00329     ngram_model_free(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>);
<a name="l00330"></a>00330 
<a name="l00331"></a>00331     ckd_free(ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>);
<a name="l00332"></a>00332     ckd_free(ngs-&gt;word_lat_idx);
<a name="l00333"></a>00333     bitvec_free(ngs-&gt;<a class="code" href="structngram__search__s.html#aeb4c98851bf9b239ca607ca59f59ff4c" title="array of active flags for all words.">word_active</a>);
<a name="l00334"></a>00334     ckd_free(ngs-&gt;bp_table);
<a name="l00335"></a>00335     ckd_free(ngs-&gt;bscore_stack);
<a name="l00336"></a>00336     <span class="keywordflow">if</span> (ngs-&gt;bp_table_idx != NULL)
<a name="l00337"></a>00337         ckd_free(ngs-&gt;bp_table_idx - 1);
<a name="l00338"></a>00338     ckd_free_2d(ngs-&gt;<a class="code" href="structngram__search__s.html#a5056573bf95990cc28c97a56cd76ce9a" title="Array of active multi-phone words for current and next frame.">active_word_list</a>);
<a name="l00339"></a>00339     ckd_free(ngs-&gt;last_ltrans);
<a name="l00340"></a>00340     ckd_free(ngs);
<a name="l00341"></a>00341 }
<a name="l00342"></a>00342 
<a name="l00343"></a>00343 <span class="keywordtype">int</span>
<a name="l00344"></a><a class="code" href="ngram__search_8h.html#a7772e007b7d7fdf437c87aeb08b59c71">00344</a> <a class="code" href="ngram__search_8c.html#a7772e007b7d7fdf437c87aeb08b59c71" title="Record the current frame&amp;#39;s index in the backpointer table.">ngram_search_mark_bptable</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <span class="keywordtype">int</span> frame_idx)
<a name="l00345"></a>00345 {
<a name="l00346"></a>00346     <span class="keywordflow">if</span> (frame_idx &gt;= ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a>) {
<a name="l00347"></a>00347         ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a> *= 2;
<a name="l00348"></a>00348         ngs-&gt;bp_table_idx = ckd_realloc(ngs-&gt;bp_table_idx - 1,
<a name="l00349"></a>00349                                         (ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a> + 1)
<a name="l00350"></a>00350                                         * <span class="keyword">sizeof</span>(*ngs-&gt;bp_table_idx));
<a name="l00351"></a>00351         <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#aa54544457c363ccccb87fc7ec63a5f3e" title="List of active words in each frame.">frm_wordlist</a>) {
<a name="l00352"></a>00352             ngs-&gt;<a class="code" href="structngram__search__s.html#aa54544457c363ccccb87fc7ec63a5f3e" title="List of active words in each frame.">frm_wordlist</a> = ckd_realloc(ngs-&gt;<a class="code" href="structngram__search__s.html#aa54544457c363ccccb87fc7ec63a5f3e" title="List of active words in each frame.">frm_wordlist</a>,
<a name="l00353"></a>00353                                             ngs-&gt;<a class="code" href="structngram__search__s.html#a38ea5de504b3d7ad2390a3f8966d502f" title="Number of frames allocated in bp_table_idx and friends.">n_frame_alloc</a>
<a name="l00354"></a>00354                                             * <span class="keyword">sizeof</span>(*ngs-&gt;<a class="code" href="structngram__search__s.html#aa54544457c363ccccb87fc7ec63a5f3e" title="List of active words in each frame.">frm_wordlist</a>));
<a name="l00355"></a>00355         }
<a name="l00356"></a>00356         ++ngs-&gt;bp_table_idx; <span class="comment">/* Make bptableidx[-1] valid */</span>
<a name="l00357"></a>00357     }
<a name="l00358"></a>00358     ngs-&gt;bp_table_idx[frame_idx] = ngs-&gt;bpidx;
<a name="l00359"></a>00359     <span class="keywordflow">return</span> ngs-&gt;bpidx;
<a name="l00360"></a>00360 }
<a name="l00361"></a>00361 
<a name="l00362"></a>00362 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00363"></a>00363 set_real_wid(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, int32 bp)
<a name="l00364"></a>00364 {
<a name="l00365"></a>00365     <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *ent, *prev;
<a name="l00366"></a>00366 
<a name="l00367"></a>00367     assert(bp != NO_BP);
<a name="l00368"></a>00368     ent = ngs-&gt;bp_table + bp;
<a name="l00369"></a>00369     <span class="keywordflow">if</span> (ent-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == NO_BP)
<a name="l00370"></a>00370         prev = NULL;
<a name="l00371"></a>00371     <span class="keywordflow">else</span>
<a name="l00372"></a>00372         prev = ngs-&gt;bp_table + ent-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00373"></a>00373 
<a name="l00374"></a>00374     <span class="comment">/* Propagate lm state for fillers, rotate it for words. */</span>
<a name="l00375"></a>00375     <span class="keywordflow">if</span> (dict_filler_word(ps_search_dict(ngs), ent-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>)) {
<a name="l00376"></a>00376         <span class="keywordflow">if</span> (prev != NULL) {
<a name="l00377"></a>00377             ent-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a> = prev-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>;
<a name="l00378"></a>00378             ent-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a> = prev-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>;
<a name="l00379"></a>00379         }
<a name="l00380"></a>00380         <span class="keywordflow">else</span> {
<a name="l00381"></a>00381             ent-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a> = dict_basewid(ps_search_dict(ngs),
<a name="l00382"></a>00382                                          ent-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>);
<a name="l00383"></a>00383             ent-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a> = <a class="code" href="s3types_8h.html#a5c42410b7125da611210c5a4be29898b" title="Dictionary word id.">BAD_S3WID</a>;
<a name="l00384"></a>00384         }
<a name="l00385"></a>00385     }
<a name="l00386"></a>00386     <span class="keywordflow">else</span> {
<a name="l00387"></a>00387         ent-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a> = dict_basewid(ps_search_dict(ngs), ent-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>);
<a name="l00388"></a>00388         <span class="keywordflow">if</span> (prev != NULL)
<a name="l00389"></a>00389             ent-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a> = prev-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>;
<a name="l00390"></a>00390         <span class="keywordflow">else</span>
<a name="l00391"></a>00391             ent-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a> = <a class="code" href="s3types_8h.html#a5c42410b7125da611210c5a4be29898b" title="Dictionary word id.">BAD_S3WID</a>;
<a name="l00392"></a>00392     }
<a name="l00393"></a>00393 }
<a name="l00394"></a>00394 
<a name="l00395"></a>00395 <span class="keywordtype">void</span>
<a name="l00396"></a><a class="code" href="ngram__search_8h.html#ae36649be6f5a2190e759e7ed13bd7b6b">00396</a> <a class="code" href="ngram__search_8c.html#ae36649be6f5a2190e759e7ed13bd7b6b" title="Enter a word in the backpointer table.">ngram_search_save_bp</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <span class="keywordtype">int</span> frame_idx,
<a name="l00397"></a>00397                      int32 w, int32 score, int32 path, int32 rc)
<a name="l00398"></a>00398 {
<a name="l00399"></a>00399     int32 bp;
<a name="l00400"></a>00400 
<a name="l00401"></a>00401     <span class="comment">/* Look for an existing exit for this word in this frame.  The</span>
<a name="l00402"></a>00402 <span class="comment">     * only reason one would exist is from a different right context</span>
<a name="l00403"></a>00403 <span class="comment">     * triphone, but of course that happens quite frequently. */</span>
<a name="l00404"></a>00404     bp = ngs-&gt;word_lat_idx[w];
<a name="l00405"></a>00405     <span class="keywordflow">if</span> (bp != NO_BP) {
<a name="l00406"></a>00406         <span class="comment">/* Keep only the best scoring one, we will reconstruct the</span>
<a name="l00407"></a>00407 <span class="comment">         * others from the right context scores - usually the history</span>
<a name="l00408"></a>00408 <span class="comment">         * is not lost. */</span>
<a name="l00409"></a>00409         <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> <a class="code" href="hmm_8h.html#aa930fb8fb6fce7f34bcf4018b81d7066" title="Is one score worse than another?">WORSE_THAN</a> score) {
<a name="l00410"></a>00410             assert(path != bp); <span class="comment">/* Pathological. */</span>
<a name="l00411"></a>00411             <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> != path) {
<a name="l00412"></a>00412                 int32 bplh[2], newlh[2];
<a name="l00413"></a>00413                 <span class="comment">/* But, sometimes, the history *is* lost.  If we wanted to</span>
<a name="l00414"></a>00414 <span class="comment">                 * do exact language model scoring we&#39;d have to preserve</span>
<a name="l00415"></a>00415 <span class="comment">                 * these alternate histories. */</span>
<a name="l00416"></a>00416                 E_DEBUG(2,(<span class="stringliteral">&quot;Updating path history %d =&gt; %d frame %d\n&quot;</span>,
<a name="l00417"></a>00417                            ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>, path, frame_idx));
<a name="l00418"></a>00418                 bplh[0] = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == -1
<a name="l00419"></a>00419                     ? -1 : ngs-&gt;bp_table[ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>].<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>;
<a name="l00420"></a>00420                 bplh[1] = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == -1
<a name="l00421"></a>00421                     ? -1 : ngs-&gt;bp_table[ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>].<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>;
<a name="l00422"></a>00422                 newlh[0] = path == -1
<a name="l00423"></a>00423                     ? -1 : ngs-&gt;bp_table[path].<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>;
<a name="l00424"></a>00424                 newlh[1] = path == -1
<a name="l00425"></a>00425                     ? -1 : ngs-&gt;bp_table[path].<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>;
<a name="l00426"></a>00426                 <span class="comment">/* Actually it&#39;s worth checking how often the actual</span>
<a name="l00427"></a>00427 <span class="comment">                 * language model state changes. */</span>
<a name="l00428"></a>00428                 <span class="keywordflow">if</span> (bplh[0] != newlh[0] || bplh[1] != newlh[1]) {
<a name="l00429"></a>00429                     <span class="comment">/* It&#39;s fairly rare that the actual language model</span>
<a name="l00430"></a>00430 <span class="comment">                     * state changes, but it does happen some</span>
<a name="l00431"></a>00431 <span class="comment">                     * times. */</span>
<a name="l00432"></a>00432                     E_DEBUG(1, (<span class="stringliteral">&quot;Updating language model state %s,%s =&gt; %s,%s frame %d\n&quot;</span>,
<a name="l00433"></a>00433                                 dict_wordstr(ps_search_dict(ngs), bplh[0]),
<a name="l00434"></a>00434                                 dict_wordstr(ps_search_dict(ngs), bplh[1]),
<a name="l00435"></a>00435                                 dict_wordstr(ps_search_dict(ngs), newlh[0]),
<a name="l00436"></a>00436                                 dict_wordstr(ps_search_dict(ngs), newlh[1]),
<a name="l00437"></a>00437                                 frame_idx));
<a name="l00438"></a>00438                     set_real_wid(ngs, bp);
<a name="l00439"></a>00439                 }
<a name="l00440"></a>00440                 ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> = path;
<a name="l00441"></a>00441             }
<a name="l00442"></a>00442             ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> = score;
<a name="l00443"></a>00443         }
<a name="l00444"></a>00444         <span class="comment">/* But do keep track of scores for all right contexts, since</span>
<a name="l00445"></a>00445 <span class="comment">         * we need them to determine the starting path scores for any</span>
<a name="l00446"></a>00446 <span class="comment">         * successors of this word exit. */</span>
<a name="l00447"></a>00447         <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> != -1)
<a name="l00448"></a>00448             ngs-&gt;bscore_stack[ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> + rc] = score;
<a name="l00449"></a>00449     }
<a name="l00450"></a>00450     <span class="keywordflow">else</span> {
<a name="l00451"></a>00451         int32 i, rcsize;
<a name="l00452"></a>00452         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be;
<a name="l00453"></a>00453 
<a name="l00454"></a>00454         <span class="comment">/* This might happen if recognition fails. */</span>
<a name="l00455"></a>00455         <span class="keywordflow">if</span> (ngs-&gt;bpidx == NO_BP) {
<a name="l00456"></a>00456             E_ERROR(<span class="stringliteral">&quot;No entries in backpointer table!&quot;</span>);
<a name="l00457"></a>00457             <span class="keywordflow">return</span>;
<a name="l00458"></a>00458         }
<a name="l00459"></a>00459 
<a name="l00460"></a>00460         <span class="comment">/* Expand the backpointer tables if necessary. */</span>
<a name="l00461"></a>00461         <span class="keywordflow">if</span> (ngs-&gt;bpidx &gt;= ngs-&gt;bp_table_size) {
<a name="l00462"></a>00462             ngs-&gt;bp_table_size *= 2;
<a name="l00463"></a>00463             ngs-&gt;bp_table = ckd_realloc(ngs-&gt;bp_table,
<a name="l00464"></a>00464                                         ngs-&gt;bp_table_size
<a name="l00465"></a>00465                                         * <span class="keyword">sizeof</span>(*ngs-&gt;bp_table));
<a name="l00466"></a>00466             E_INFO(<span class="stringliteral">&quot;Resized backpointer table to %d entries\n&quot;</span>, ngs-&gt;bp_table_size);
<a name="l00467"></a>00467         }
<a name="l00468"></a>00468         <span class="keywordflow">if</span> (ngs-&gt;bss_head &gt;= ngs-&gt;bscore_stack_size
<a name="l00469"></a>00469             - bin_mdef_n_ciphone(ps_search_acmod(ngs)-&gt;mdef)) {
<a name="l00470"></a>00470             ngs-&gt;bscore_stack_size *= 2;
<a name="l00471"></a>00471             ngs-&gt;bscore_stack = ckd_realloc(ngs-&gt;bscore_stack,
<a name="l00472"></a>00472                                             ngs-&gt;bscore_stack_size
<a name="l00473"></a>00473                                             * <span class="keyword">sizeof</span>(*ngs-&gt;bscore_stack));
<a name="l00474"></a>00474             E_INFO(<span class="stringliteral">&quot;Resized score stack to %d entries\n&quot;</span>, ngs-&gt;bscore_stack_size);
<a name="l00475"></a>00475         }
<a name="l00476"></a>00476 
<a name="l00477"></a>00477         ngs-&gt;word_lat_idx[w] = ngs-&gt;bpidx;
<a name="l00478"></a>00478         be = &amp;(ngs-&gt;bp_table[ngs-&gt;bpidx]);
<a name="l00479"></a>00479         be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> = w;
<a name="l00480"></a>00480         be-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> = frame_idx;
<a name="l00481"></a>00481         be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> = path;
<a name="l00482"></a>00482         be-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> = score;
<a name="l00483"></a>00483         be-&gt;<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> = ngs-&gt;bss_head;
<a name="l00484"></a>00484         be-&gt;<a class="code" href="structbptbl__s.html#a4948439666e1e2204a6d1c6d9cfd1cd0" title="For absolute pruning.">valid</a> = TRUE;
<a name="l00485"></a>00485         assert(path != ngs-&gt;bpidx);
<a name="l00486"></a>00486 
<a name="l00487"></a>00487         <span class="comment">/* DICT2PID */</span>
<a name="l00488"></a>00488         <span class="comment">/* Get diphone ID for final phone and number of ssids corresponding to it. */</span>
<a name="l00489"></a>00489         be-&gt;<a class="code" href="structbptbl__s.html#aa7704ba76d3dcde6b8a24855362a4289" title="last phone of this word">last_phone</a> = dict_last_phone(ps_search_dict(ngs),w);
<a name="l00490"></a>00490         <span class="keywordflow">if</span> (dict_is_single_phone(ps_search_dict(ngs), w)) {
<a name="l00491"></a>00491             be-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a> = -1;
<a name="l00492"></a>00492             be-&gt;<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> = -1;
<a name="l00493"></a>00493             rcsize = 0;
<a name="l00494"></a>00494         }
<a name="l00495"></a>00495         <span class="keywordflow">else</span> {
<a name="l00496"></a>00496             be-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a> = dict_second_last_phone(ps_search_dict(ngs),w);
<a name="l00497"></a>00497             rcsize = <a class="code" href="dict2pid_8h.html#a453a98931cad95a19b4c4ab770fc79f1" title="Access macros; not designed for arbitrary use.">dict2pid_rssid</a>(ps_search_dict2pid(ngs),
<a name="l00498"></a>00498                                     be-&gt;<a class="code" href="structbptbl__s.html#aa7704ba76d3dcde6b8a24855362a4289" title="last phone of this word">last_phone</a>, be-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a>)-&gt;n_ssid;
<a name="l00499"></a>00499         }
<a name="l00500"></a>00500         <span class="comment">/* Allocate some space on the bscore_stack for all of these triphones. */</span>
<a name="l00501"></a>00501         <span class="keywordflow">for</span> (i = 0; i &lt; rcsize; ++i)
<a name="l00502"></a>00502             ngs-&gt;bscore_stack[ngs-&gt;bss_head + i] = <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>;
<a name="l00503"></a>00503         if (rcsize)
<a name="l00504"></a>00504             ngs-&gt;bscore_stack[ngs-&gt;bss_head + rc] = score;
<a name="l00505"></a>00505         set_real_wid(ngs, ngs-&gt;bpidx);
<a name="l00506"></a>00506 
<a name="l00507"></a>00507         ngs-&gt;bpidx++;
<a name="l00508"></a>00508         ngs-&gt;bss_head += rcsize;
<a name="l00509"></a>00509     }
<a name="l00510"></a>00510 }
<a name="l00511"></a>00511 
<a name="l00512"></a>00512 <span class="keywordtype">int</span>
<a name="l00513"></a><a class="code" href="ngram__search_8h.html#aa4b308f06bdf75b2f5eb0f0559f775ae">00513</a> <a class="code" href="ngram__search_8c.html#aa4b308f06bdf75b2f5eb0f0559f775ae" title="Find the best word exit for the current frame in the backpointer table.">ngram_search_find_exit</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <span class="keywordtype">int</span> frame_idx, int32 *out_best_score)
<a name="l00514"></a>00514 {
<a name="l00515"></a>00515     <span class="comment">/* End of backpointers for this frame. */</span>
<a name="l00516"></a>00516     <span class="keywordtype">int</span> end_bpidx;
<a name="l00517"></a>00517     <span class="keywordtype">int</span> best_exit, bp;
<a name="l00518"></a>00518     int32 best_score;
<a name="l00519"></a>00519 
<a name="l00520"></a>00520     <span class="comment">/* No hypothesis means no exit node! */</span>
<a name="l00521"></a>00521     <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a> == 0)
<a name="l00522"></a>00522         <span class="keywordflow">return</span> NO_BP;
<a name="l00523"></a>00523 
<a name="l00524"></a>00524     <span class="keywordflow">if</span> (frame_idx == -1 || frame_idx &gt;= ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a>)
<a name="l00525"></a>00525         frame_idx = ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a> - 1;
<a name="l00526"></a>00526     end_bpidx = ngs-&gt;bp_table_idx[frame_idx];
<a name="l00527"></a>00527 
<a name="l00528"></a>00528     best_score = <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>;
<a name="l00529"></a>00529     best_exit = NO_BP;
<a name="l00530"></a>00530 
<a name="l00531"></a>00531     <span class="comment">/* Scan back to find a frame with some backpointers in it. */</span>
<a name="l00532"></a>00532     <span class="keywordflow">while</span> (frame_idx &gt;= 0 &amp;&amp; ngs-&gt;bp_table_idx[frame_idx] == end_bpidx)
<a name="l00533"></a>00533         --frame_idx;
<a name="l00534"></a>00534     <span class="comment">/* This is NOT an error, it just means there is no hypothesis yet. */</span>
<a name="l00535"></a>00535     <span class="keywordflow">if</span> (frame_idx &lt; 0)
<a name="l00536"></a>00536         <span class="keywordflow">return</span> NO_BP;
<a name="l00537"></a>00537 
<a name="l00538"></a>00538     <span class="comment">/* Now find the entry for &lt;/s&gt; OR the best scoring entry. */</span>
<a name="l00539"></a>00539     assert(end_bpidx &lt; ngs-&gt;bp_table_size);
<a name="l00540"></a>00540     <span class="keywordflow">for</span> (bp = ngs-&gt;bp_table_idx[frame_idx]; bp &lt; end_bpidx; ++bp) {
<a name="l00541"></a>00541         <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> == ps_search_finish_wid(ngs)
<a name="l00542"></a>00542             || ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> best_score) {
<a name="l00543"></a>00543             best_score = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>;
<a name="l00544"></a>00544             best_exit = bp;
<a name="l00545"></a>00545         }
<a name="l00546"></a>00546         <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> == ps_search_finish_wid(ngs))
<a name="l00547"></a>00547             <span class="keywordflow">break</span>;
<a name="l00548"></a>00548     }
<a name="l00549"></a>00549 
<a name="l00550"></a>00550     <span class="keywordflow">if</span> (out_best_score) *out_best_score = best_score;
<a name="l00551"></a>00551     <span class="keywordflow">return</span> best_exit;
<a name="l00552"></a>00552 }
<a name="l00553"></a>00553 
<a name="l00554"></a>00554 <span class="keywordtype">char</span> <span class="keyword">const</span> *
<a name="l00555"></a><a class="code" href="ngram__search_8h.html#aee393a136f8f7e8b98161e6eed7b1dd9">00555</a> <a class="code" href="ngram__search_8c.html#aee393a136f8f7e8b98161e6eed7b1dd9" title="Backtrace from a given backpointer index to obtain a word hypothesis.">ngram_search_bp_hyp</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <span class="keywordtype">int</span> bpidx)
<a name="l00556"></a>00556 {
<a name="l00557"></a>00557     <a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *base = ps_search_base(ngs);
<a name="l00558"></a>00558     <span class="keywordtype">char</span> *c;
<a name="l00559"></a>00559     <span class="keywordtype">size_t</span> len;
<a name="l00560"></a>00560     <span class="keywordtype">int</span> bp;
<a name="l00561"></a>00561 
<a name="l00562"></a>00562     <span class="keywordflow">if</span> (bpidx == NO_BP)
<a name="l00563"></a>00563         <span class="keywordflow">return</span> NULL;
<a name="l00564"></a>00564 
<a name="l00565"></a>00565     bp = bpidx;
<a name="l00566"></a>00566     len = 0;
<a name="l00567"></a>00567     <span class="keywordflow">while</span> (bp != NO_BP) {
<a name="l00568"></a>00568         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be = &amp;ngs-&gt;bp_table[bp];
<a name="l00569"></a>00569         bp = be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00570"></a>00570         <span class="keywordflow">if</span> (dict_real_word(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>))
<a name="l00571"></a>00571             len += strlen(dict_basestr(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>)) + 1;
<a name="l00572"></a>00572     }
<a name="l00573"></a>00573 
<a name="l00574"></a>00574     ckd_free(base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>);
<a name="l00575"></a>00575     <span class="keywordflow">if</span> (len == 0) {
<a name="l00576"></a>00576         base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> = NULL;
<a name="l00577"></a>00577         <span class="keywordflow">return</span> base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>;
<a name="l00578"></a>00578     }
<a name="l00579"></a>00579     base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> = ckd_calloc(1, len);
<a name="l00580"></a>00580 
<a name="l00581"></a>00581     bp = bpidx;
<a name="l00582"></a>00582     c = base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> + len - 1;
<a name="l00583"></a>00583     <span class="keywordflow">while</span> (bp != NO_BP) {
<a name="l00584"></a>00584         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be = &amp;ngs-&gt;bp_table[bp];
<a name="l00585"></a>00585         <span class="keywordtype">size_t</span> len;
<a name="l00586"></a>00586 
<a name="l00587"></a>00587         bp = be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00588"></a>00588         <span class="keywordflow">if</span> (dict_real_word(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>)) {
<a name="l00589"></a>00589             len = strlen(dict_basestr(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>));
<a name="l00590"></a>00590             c -= len;
<a name="l00591"></a>00591             memcpy(c, dict_basestr(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>), len);
<a name="l00592"></a>00592             <span class="keywordflow">if</span> (c &gt; base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>) {
<a name="l00593"></a>00593                 --c;
<a name="l00594"></a>00594                 *c = <span class="charliteral">&#39; &#39;</span>;
<a name="l00595"></a>00595             }
<a name="l00596"></a>00596         }
<a name="l00597"></a>00597     }
<a name="l00598"></a>00598 
<a name="l00599"></a>00599     <span class="keywordflow">return</span> base-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>;
<a name="l00600"></a>00600 }
<a name="l00601"></a>00601 
<a name="l00602"></a>00602 <span class="keywordtype">void</span>
<a name="l00603"></a><a class="code" href="ngram__search_8h.html#a1ddcc1a9cb3e164ceb2140097ed23a3e">00603</a> <a class="code" href="ngram__search_8c.html#a1ddcc1a9cb3e164ceb2140097ed23a3e" title="Allocate last phone channels for all possible right contexts for word w.">ngram_search_alloc_all_rc</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, int32 w)
<a name="l00604"></a>00604 {
<a name="l00605"></a>00605     <a class="code" href="structchan__s.html" title="Lexical tree node data type.">chan_t</a> *hmm, *thmm;
<a name="l00606"></a>00606     <a class="code" href="structxwdssid__t.html" title="cross word triphone model structure">xwdssid_t</a> *rssid;
<a name="l00607"></a>00607     int32 i, tmatid, ciphone;
<a name="l00608"></a>00608 
<a name="l00609"></a>00609     <span class="comment">/* DICT2PID */</span>
<a name="l00610"></a>00610     <span class="comment">/* Get pointer to array of triphones for final diphone. */</span>
<a name="l00611"></a>00611     assert(!dict_is_single_phone(ps_search_dict(ngs), w));
<a name="l00612"></a>00612     ciphone = dict_last_phone(ps_search_dict(ngs),w);
<a name="l00613"></a>00613     rssid = <a class="code" href="dict2pid_8h.html#a453a98931cad95a19b4c4ab770fc79f1" title="Access macros; not designed for arbitrary use.">dict2pid_rssid</a>(ps_search_dict2pid(ngs),
<a name="l00614"></a>00614                            ciphone,
<a name="l00615"></a>00615                            dict_second_last_phone(ps_search_dict(ngs),w));
<a name="l00616"></a>00616     tmatid = bin_mdef_pid2tmatid(ps_search_acmod(ngs)-&gt;mdef, ciphone);
<a name="l00617"></a>00617     hmm = ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>[w];
<a name="l00618"></a>00618     <span class="keywordflow">if</span> ((hmm == NULL) || (hmm_nonmpx_ssid(&amp;hmm-&gt;<a class="code" href="structchan__s.html#a742d6a125ac468b95a1ddd880a956e35" title="Basic HMM structure.">hmm</a>) != rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[0])) {
<a name="l00619"></a>00619         hmm = listelem_malloc(ngs-&gt;<a class="code" href="structngram__search__s.html#abe9fe60f6e48b9a6e3d41856bb1dc109" title="For chan_t.">chan_alloc</a>);
<a name="l00620"></a>00620         hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a> = ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>[w];
<a name="l00621"></a>00621         ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>[w] = hmm;
<a name="l00622"></a>00622 
<a name="l00623"></a>00623         hmm-&gt;info.<a class="code" href="structchan__s.html#acf84a2fa662e7ff626769e7d8152a608" title="right-context id for last phone of words">rc_id</a> = 0;
<a name="l00624"></a>00624         hmm-&gt;<a class="code" href="structchan__s.html#a33da51d8524073abc792519d0738ca0b" title="ciphone for this node">ciphone</a> = ciphone;
<a name="l00625"></a>00625         hmm_init(ngs-&gt;<a class="code" href="structngram__search__s.html#acfbdd34e3dadbaa384818402f1dd59bf" title="HMM context.">hmmctx</a>, &amp;hmm-&gt;<a class="code" href="structchan__s.html#a742d6a125ac468b95a1ddd880a956e35" title="Basic HMM structure.">hmm</a>, FALSE, rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[0], tmatid);
<a name="l00626"></a>00626         E_DEBUG(3,(<span class="stringliteral">&quot;allocated rc_id 0 ssid %d ciphone %d lc %d word %s\n&quot;</span>,
<a name="l00627"></a>00627                    rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[0], hmm-&gt;<a class="code" href="structchan__s.html#a33da51d8524073abc792519d0738ca0b" title="ciphone for this node">ciphone</a>,
<a name="l00628"></a>00628                    dict_second_last_phone(ps_search_dict(ngs),w),
<a name="l00629"></a>00629                    dict_wordstr(ps_search_dict(ngs),w)));
<a name="l00630"></a>00630     }
<a name="l00631"></a>00631     <span class="keywordflow">for</span> (i = 1; i &lt; rssid-&gt;<a class="code" href="structxwdssid__t.html#ab4443c642c5aff57c35abed070112d6e" title="#Unique ssid in above, compressed ssid list">n_ssid</a>; ++i) {
<a name="l00632"></a>00632         <span class="keywordflow">if</span> ((hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a> == NULL) || (hmm_nonmpx_ssid(&amp;hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a>-&gt;<a class="code" href="structchan__s.html#a742d6a125ac468b95a1ddd880a956e35" title="Basic HMM structure.">hmm</a>) != rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[i])) {
<a name="l00633"></a>00633             thmm = listelem_malloc(ngs-&gt;<a class="code" href="structngram__search__s.html#abe9fe60f6e48b9a6e3d41856bb1dc109" title="For chan_t.">chan_alloc</a>);
<a name="l00634"></a>00634             thmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a> = hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a>;
<a name="l00635"></a>00635             hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a> = thmm;
<a name="l00636"></a>00636             hmm = thmm;
<a name="l00637"></a>00637 
<a name="l00638"></a>00638             hmm-&gt;info.<a class="code" href="structchan__s.html#acf84a2fa662e7ff626769e7d8152a608" title="right-context id for last phone of words">rc_id</a> = i;
<a name="l00639"></a>00639             hmm-&gt;<a class="code" href="structchan__s.html#a33da51d8524073abc792519d0738ca0b" title="ciphone for this node">ciphone</a> = ciphone;
<a name="l00640"></a>00640             hmm_init(ngs-&gt;<a class="code" href="structngram__search__s.html#acfbdd34e3dadbaa384818402f1dd59bf" title="HMM context.">hmmctx</a>, &amp;hmm-&gt;<a class="code" href="structchan__s.html#a742d6a125ac468b95a1ddd880a956e35" title="Basic HMM structure.">hmm</a>, FALSE, rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[i], tmatid);
<a name="l00641"></a>00641             E_DEBUG(3,(<span class="stringliteral">&quot;allocated rc_id %d ssid %d ciphone %d lc %d word %s\n&quot;</span>,
<a name="l00642"></a>00642                        i, rssid-&gt;<a class="code" href="structxwdssid__t.html#adbeeda6e94a51f08626c13414cdad6a8" title="Senone Sequence ID list for all context ciphones.">ssid</a>[i], hmm-&gt;<a class="code" href="structchan__s.html#a33da51d8524073abc792519d0738ca0b" title="ciphone for this node">ciphone</a>,
<a name="l00643"></a>00643                        dict_second_last_phone(ps_search_dict(ngs),w),
<a name="l00644"></a>00644                        dict_wordstr(ps_search_dict(ngs),w)));
<a name="l00645"></a>00645         }
<a name="l00646"></a>00646         <span class="keywordflow">else</span>
<a name="l00647"></a>00647             hmm = hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a>;
<a name="l00648"></a>00648     }
<a name="l00649"></a>00649 }
<a name="l00650"></a>00650 
<a name="l00651"></a>00651 <span class="keywordtype">void</span>
<a name="l00652"></a><a class="code" href="ngram__search_8h.html#a15477192481dffcb29e9c4167eff6c3c">00652</a> <a class="code" href="ngram__search_8c.html#a15477192481dffcb29e9c4167eff6c3c" title="Allocate last phone channels for all possible right contexts for word w.">ngram_search_free_all_rc</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, int32 w)
<a name="l00653"></a>00653 {
<a name="l00654"></a>00654     <a class="code" href="structchan__s.html" title="Lexical tree node data type.">chan_t</a> *hmm, *thmm;
<a name="l00655"></a>00655 
<a name="l00656"></a>00656     <span class="keywordflow">for</span> (hmm = ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>[w]; hmm; hmm = thmm) {
<a name="l00657"></a>00657         thmm = hmm-&gt;<a class="code" href="structchan__s.html#a260b68eff64150d0ae9ce4db7feb1300" title="first descendant of this channel; or, in the case of the last phone of a word, the next alternative r...">next</a>;
<a name="l00658"></a>00658         hmm_deinit(&amp;hmm-&gt;<a class="code" href="structchan__s.html#a742d6a125ac468b95a1ddd880a956e35" title="Basic HMM structure.">hmm</a>);
<a name="l00659"></a>00659         listelem_free(ngs-&gt;<a class="code" href="structngram__search__s.html#abe9fe60f6e48b9a6e3d41856bb1dc109" title="For chan_t.">chan_alloc</a>, hmm);
<a name="l00660"></a>00660     }
<a name="l00661"></a>00661     ngs-&gt;<a class="code" href="structngram__search__s.html#a79deb7295a261cd82d2a6b48cb119e77" title="Channels associated with a given word (only used for right contexts, single-phone words in fwdtree se...">word_chan</a>[w] = NULL;
<a name="l00662"></a>00662 }
<a name="l00663"></a>00663 
<a name="l00664"></a>00664 int32
<a name="l00665"></a><a class="code" href="ngram__search_8h.html#a25a80e488425b2bd4e24eb753c9295a5">00665</a> <a class="code" href="ngram__search_8c.html#a25a80e488425b2bd4e24eb753c9295a5" title="Get the exit score for a backpointer entry with a given right context.">ngram_search_exit_score</a>(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *pbe, <span class="keywordtype">int</span> rcphone)
<a name="l00666"></a>00666 {
<a name="l00667"></a>00667     <span class="comment">/* DICT2PID */</span>
<a name="l00668"></a>00668     <span class="comment">/* Get the mapping from right context phone ID to index in the</span>
<a name="l00669"></a>00669 <span class="comment">     * right context table and the bscore_stack. */</span>
<a name="l00670"></a>00670     <span class="keywordflow">if</span> (pbe-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a> == -1) {
<a name="l00671"></a>00671         <span class="comment">/* No right context for single phone predecessor words. */</span>
<a name="l00672"></a>00672         <span class="keywordflow">return</span> pbe-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>;
<a name="l00673"></a>00673     }
<a name="l00674"></a>00674     <span class="keywordflow">else</span> {
<a name="l00675"></a>00675         <a class="code" href="structxwdssid__t.html" title="cross word triphone model structure">xwdssid_t</a> *rssid;
<a name="l00676"></a>00676         <span class="comment">/* Find the index for the last diphone of the previous word +</span>
<a name="l00677"></a>00677 <span class="comment">         * the first phone of the current word. */</span>
<a name="l00678"></a>00678         rssid = <a class="code" href="dict2pid_8h.html#a453a98931cad95a19b4c4ab770fc79f1" title="Access macros; not designed for arbitrary use.">dict2pid_rssid</a>(ps_search_dict2pid(ngs),
<a name="l00679"></a>00679                                pbe-&gt;<a class="code" href="structbptbl__s.html#aa7704ba76d3dcde6b8a24855362a4289" title="last phone of this word">last_phone</a>, pbe-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a>);
<a name="l00680"></a>00680         <span class="comment">/* This may be WORST_SCORE, which means that there was no exit</span>
<a name="l00681"></a>00681 <span class="comment">         * with rcphone as right context. */</span>
<a name="l00682"></a>00682         <span class="keywordflow">return</span> ngs-&gt;bscore_stack[pbe-&gt;<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> + rssid-&gt;<a class="code" href="structxwdssid__t.html#a502f9241a70383aa260d3390e4ff58fb" title="Index into ssid[] above for each ci phone.">cimap</a>[rcphone]];
<a name="l00683"></a>00683     }
<a name="l00684"></a>00684 }
<a name="l00685"></a>00685 
<a name="l00686"></a>00686 <span class="comment">/*</span>
<a name="l00687"></a>00687 <span class="comment"> * Compute acoustic and LM scores for a BPTable entry (segment).</span>
<a name="l00688"></a>00688 <span class="comment"> */</span>
<a name="l00689"></a>00689 <span class="keywordtype">void</span>
<a name="l00690"></a>00690 ngram_compute_seg_score(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be, float32 lwf,
<a name="l00691"></a>00691                         int32 *out_ascr, int32 *out_lscr)
<a name="l00692"></a>00692 {
<a name="l00693"></a>00693     <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *pbe;
<a name="l00694"></a>00694     int32 start_score;
<a name="l00695"></a>00695 
<a name="l00696"></a>00696     <span class="comment">/* Start of utterance. */</span>
<a name="l00697"></a>00697     <span class="keywordflow">if</span> (be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == NO_BP) {
<a name="l00698"></a>00698         *out_ascr = be-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>;
<a name="l00699"></a>00699         *out_lscr = 0;
<a name="l00700"></a>00700         <span class="keywordflow">return</span>;
<a name="l00701"></a>00701     }
<a name="l00702"></a>00702 
<a name="l00703"></a>00703     <span class="comment">/* Otherwise, calculate lscr and ascr. */</span>
<a name="l00704"></a>00704     pbe = ngs-&gt;bp_table + be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00705"></a>00705     start_score = <a class="code" href="ngram__search_8c.html#a25a80e488425b2bd4e24eb753c9295a5" title="Get the exit score for a backpointer entry with a given right context.">ngram_search_exit_score</a>(ngs, pbe,
<a name="l00706"></a>00706                                  dict_first_phone(ps_search_dict(ngs),be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>));
<a name="l00707"></a>00707     assert(start_score <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>);
<a name="l00708"></a>00708 
<a name="l00709"></a>00709     <span class="comment">/* FIXME: These result in positive acoustic scores when filler</span>
<a name="l00710"></a>00710 <span class="comment">       words have non-filler pronunciations.  That whole business</span>
<a name="l00711"></a>00711 <span class="comment">       is still pretty much broken but at least it doesn&#39;t</span>
<a name="l00712"></a>00712 <span class="comment">       segfault. */</span>
<a name="l00713"></a>00713     <span class="keywordflow">if</span> (be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> == ps_search_silence_wid(ngs)) {
<a name="l00714"></a>00714         *out_lscr = ngs-&gt;silpen;
<a name="l00715"></a>00715     }
<a name="l00716"></a>00716     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (dict_filler_word(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>)) {
<a name="l00717"></a>00717         *out_lscr = ngs-&gt;fillpen;
<a name="l00718"></a>00718     }
<a name="l00719"></a>00719     <span class="keywordflow">else</span> {
<a name="l00720"></a>00720         int32 n_used;
<a name="l00721"></a>00721         *out_lscr = ngram_tg_score(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>,
<a name="l00722"></a>00722                                    be-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>,
<a name="l00723"></a>00723                                    pbe-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>,
<a name="l00724"></a>00724                                    pbe-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>,
<a name="l00725"></a>00725                                    &amp;n_used)&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00726"></a>00726         *out_lscr = *out_lscr * lwf;
<a name="l00727"></a>00727     }
<a name="l00728"></a>00728     *out_ascr = be-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> - start_score - *out_lscr;
<a name="l00729"></a>00729 }
<a name="l00730"></a>00730 
<a name="l00731"></a>00731 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00732"></a>00732 ngram_search_start(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l00733"></a>00733 {
<a name="l00734"></a>00734     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00735"></a>00735 
<a name="l00736"></a>00736     ngs-&gt;done = FALSE;
<a name="l00737"></a>00737     ngram_model_flush(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>);
<a name="l00738"></a>00738     <span class="keywordflow">if</span> (ngs-&gt;fwdtree)
<a name="l00739"></a>00739         <a class="code" href="ngram__search__fwdtree_8c.html#af736200cd01a5d743dbab447ecc85d08" title="Start fwdtree decoding for an utterance.">ngram_fwdtree_start</a>(ngs);
<a name="l00740"></a>00740     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ngs-&gt;fwdflat)
<a name="l00741"></a>00741         <a class="code" href="ngram__search__fwdflat_8c.html#a763c2c7aaa5d7f9c5107af73552a2149" title="Start fwdflat decoding for an utterance.">ngram_fwdflat_start</a>(ngs);
<a name="l00742"></a>00742     <span class="keywordflow">else</span>
<a name="l00743"></a>00743         <span class="keywordflow">return</span> -1;
<a name="l00744"></a>00744     <span class="keywordflow">return</span> 0;
<a name="l00745"></a>00745 }
<a name="l00746"></a>00746 
<a name="l00747"></a>00747 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00748"></a>00748 ngram_search_step(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, <span class="keywordtype">int</span> frame_idx)
<a name="l00749"></a>00749 {
<a name="l00750"></a>00750     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00751"></a>00751 
<a name="l00752"></a>00752     <span class="keywordflow">if</span> (ngs-&gt;fwdtree)
<a name="l00753"></a>00753         <span class="keywordflow">return</span> <a class="code" href="ngram__search__fwdtree_8c.html#a9e2828ba0d249424a234b6cf7d3ee530" title="Search one frame forward in an utterance.">ngram_fwdtree_search</a>(ngs, frame_idx);
<a name="l00754"></a>00754     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ngs-&gt;fwdflat)
<a name="l00755"></a>00755         <span class="keywordflow">return</span> <a class="code" href="ngram__search__fwdflat_8c.html#ae77ef21ae92dbcc4b14f40469fbd4307" title="Search one frame forward in an utterance.">ngram_fwdflat_search</a>(ngs, frame_idx);
<a name="l00756"></a>00756     <span class="keywordflow">else</span>
<a name="l00757"></a>00757         <span class="keywordflow">return</span> -1;
<a name="l00758"></a>00758 }
<a name="l00759"></a>00759 
<a name="l00760"></a>00760 <span class="keywordtype">void</span>
<a name="l00761"></a>00761 dump_bptable(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs)
<a name="l00762"></a>00762 {
<a name="l00763"></a>00763     <span class="keywordtype">int</span> i;
<a name="l00764"></a>00764     E_INFO(<span class="stringliteral">&quot;Backpointer table (%d entries):\n&quot;</span>, ngs-&gt;bpidx);
<a name="l00765"></a>00765     <span class="keywordflow">for</span> (i = 0; i &lt; ngs-&gt;bpidx; ++i) {
<a name="l00766"></a>00766         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *bpe = ngs-&gt;bp_table + i;
<a name="l00767"></a>00767         <span class="keywordtype">int</span> j, rcsize;
<a name="l00768"></a>00768 
<a name="l00769"></a>00769         E_INFO_NOFN(<span class="stringliteral">&quot;%-5d %-10s start %-3d end %-3d score %-8d bp %-3d real_wid %-5d prev_real_wid %-5d&quot;</span>,
<a name="l00770"></a>00770                     i, dict_wordstr(ps_search_dict(ngs), bpe-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>),
<a name="l00771"></a>00771                     (bpe-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == -1
<a name="l00772"></a>00772                      ? 0 : ngs-&gt;bp_table[bpe-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> + 1),
<a name="l00773"></a>00773                     bpe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>, bpe-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>, bpe-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>,
<a name="l00774"></a>00774                     bpe-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>, bpe-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>);
<a name="l00775"></a>00775 
<a name="l00776"></a>00776         <span class="keywordflow">if</span> (bpe-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a> == -1)
<a name="l00777"></a>00777             rcsize = 0;
<a name="l00778"></a>00778         <span class="keywordflow">else</span>
<a name="l00779"></a>00779             rcsize = <a class="code" href="dict2pid_8h.html#a453a98931cad95a19b4c4ab770fc79f1" title="Access macros; not designed for arbitrary use.">dict2pid_rssid</a>(ps_search_dict2pid(ngs),
<a name="l00780"></a>00780                                     bpe-&gt;<a class="code" href="structbptbl__s.html#aa7704ba76d3dcde6b8a24855362a4289" title="last phone of this word">last_phone</a>, bpe-&gt;<a class="code" href="structbptbl__s.html#a27b8e54bb7552e6afc15e4f44f42e3b7" title="next-to-last phone of this word">last2_phone</a>)-&gt;n_ssid;
<a name="l00781"></a>00781         <span class="keywordflow">if</span> (rcsize) {
<a name="l00782"></a>00782             E_INFOCONT(<span class="stringliteral">&quot;\tbss&quot;</span>);
<a name="l00783"></a>00783             <span class="keywordflow">for</span> (j = 0; j &lt; rcsize; ++j)
<a name="l00784"></a>00784                 <span class="keywordflow">if</span> (ngs-&gt;bscore_stack[bpe-&gt;<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> + j] != <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>)
<a name="l00785"></a>00785                     E_INFOCONT(<span class="stringliteral">&quot; %d&quot;</span>, bpe-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> - ngs-&gt;bscore_stack[bpe-&gt;<a class="code" href="structbptbl__s.html#abf9e4bcf1927aa09fb2b30c59e99f551" title="Start of BScoreStack for various right contexts.">s_idx</a> + j]);
<a name="l00786"></a>00786         }
<a name="l00787"></a>00787         E_INFOCONT(<span class="stringliteral">&quot;\n&quot;</span>);
<a name="l00788"></a>00788     }
<a name="l00789"></a>00789 }
<a name="l00790"></a>00790 
<a name="l00791"></a>00791 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00792"></a>00792 ngram_search_finish(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l00793"></a>00793 {
<a name="l00794"></a>00794     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00795"></a>00795 
<a name="l00796"></a>00796     ngs-&gt;n_tot_frame += ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a>;
<a name="l00797"></a>00797     <span class="keywordflow">if</span> (ngs-&gt;fwdtree) {
<a name="l00798"></a>00798         <a class="code" href="ngram__search__fwdtree_8c.html#af32a83dbb9187542577a0c500b000840" title="Finish fwdtree decoding for an utterance.">ngram_fwdtree_finish</a>(ngs);
<a name="l00799"></a>00799         <span class="comment">/* dump_bptable(ngs); */</span>
<a name="l00800"></a>00800 
<a name="l00801"></a>00801         <span class="comment">/* Now do fwdflat search in its entirety, if requested. */</span>
<a name="l00802"></a>00802         <span class="keywordflow">if</span> (ngs-&gt;fwdflat) {
<a name="l00803"></a>00803             <span class="keywordtype">int</span> i;
<a name="l00804"></a>00804             <span class="comment">/* Rewind the acoustic model. */</span>
<a name="l00805"></a>00805             <span class="keywordflow">if</span> (<a class="code" href="acmod_8c.html#a7b5f0b6edac2985b9b56d630cd705b99" title="Rewind the current utterance, allowing it to be rescored.">acmod_rewind</a>(ps_search_acmod(ngs)) &lt; 0)
<a name="l00806"></a>00806                 <span class="keywordflow">return</span> -1;
<a name="l00807"></a>00807             <span class="comment">/* Now redo search. */</span>
<a name="l00808"></a>00808             <a class="code" href="ngram__search__fwdflat_8c.html#a763c2c7aaa5d7f9c5107af73552a2149" title="Start fwdflat decoding for an utterance.">ngram_fwdflat_start</a>(ngs);
<a name="l00809"></a>00809             i = 0;
<a name="l00810"></a>00810             <span class="keywordflow">while</span> (ps_search_acmod(ngs)-&gt;n_feat_frame &gt; 0) {
<a name="l00811"></a>00811                 <span class="keywordtype">int</span> nfr;
<a name="l00812"></a>00812                 <span class="keywordflow">if</span> ((nfr = <a class="code" href="ngram__search__fwdflat_8c.html#ae77ef21ae92dbcc4b14f40469fbd4307" title="Search one frame forward in an utterance.">ngram_fwdflat_search</a>(ngs, i)) &lt; 0)
<a name="l00813"></a>00813                     <span class="keywordflow">return</span> nfr;
<a name="l00814"></a>00814                 <a class="code" href="acmod_8c.html#a338971ea0aa27fb4796d224e4767642b" title="Advance the frame index.">acmod_advance</a>(ps_search_acmod(ngs));
<a name="l00815"></a>00815                 ++i;
<a name="l00816"></a>00816             }
<a name="l00817"></a>00817             <a class="code" href="ngram__search__fwdflat_8c.html#ac855cf540ac4acdfa320629720ded6fe" title="Finish fwdflat decoding for an utterance.">ngram_fwdflat_finish</a>(ngs);
<a name="l00818"></a>00818             <span class="comment">/* And now, we should have a result... */</span>
<a name="l00819"></a>00819             <span class="comment">/* dump_bptable(ngs); */</span>
<a name="l00820"></a>00820         }
<a name="l00821"></a>00821     }
<a name="l00822"></a>00822     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ngs-&gt;fwdflat) {
<a name="l00823"></a>00823         <a class="code" href="ngram__search__fwdflat_8c.html#ac855cf540ac4acdfa320629720ded6fe" title="Finish fwdflat decoding for an utterance.">ngram_fwdflat_finish</a>(ngs);
<a name="l00824"></a>00824     }
<a name="l00825"></a>00825 
<a name="l00826"></a>00826     <span class="comment">/* Mark the current utterance as done. */</span>
<a name="l00827"></a>00827     ngs-&gt;done = TRUE;
<a name="l00828"></a>00828     <span class="keywordflow">return</span> 0;
<a name="l00829"></a>00829 }
<a name="l00830"></a>00830 
<a name="l00831"></a>00831 <span class="keyword">static</span> <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *
<a name="l00832"></a>00832 ngram_search_bestpath(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, int32 *out_score, <span class="keywordtype">int</span> backward)
<a name="l00833"></a>00833 {
<a name="l00834"></a>00834     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00835"></a>00835 
<a name="l00836"></a>00836     <span class="keywordflow">if</span> (search-&gt;<a class="code" href="structps__search__s.html#aa3020ef7bd4e56713dfe2fbad52e6e4f" title="Final link in best path.">last_link</a> == NULL) {
<a name="l00837"></a>00837         search-&gt;<a class="code" href="structps__search__s.html#aa3020ef7bd4e56713dfe2fbad52e6e4f" title="Final link in best path.">last_link</a> = <a class="code" href="ps__lattice_8h.html#af19b8f0749af01d4874595e80fc612ba" title="Do N-Gram based best-path search on a word graph.">ps_lattice_bestpath</a>(search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>, ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>,
<a name="l00838"></a>00838                                                 ngs-&gt;bestpath_fwdtree_lw_ratio,
<a name="l00839"></a>00839                                                 ngs-&gt;<a class="code" href="structngram__search__s.html#a1e3d4b67e4b11c6c11ebe16552d53d2d" title="Acoustic score scale for posterior probabilities.">ascale</a>);
<a name="l00840"></a>00840         <span class="keywordflow">if</span> (search-&gt;<a class="code" href="structps__search__s.html#aa3020ef7bd4e56713dfe2fbad52e6e4f" title="Final link in best path.">last_link</a> == NULL)
<a name="l00841"></a>00841             <span class="keywordflow">return</span> NULL;
<a name="l00842"></a>00842         <span class="comment">/* Also calculate betas so we can fill in the posterior</span>
<a name="l00843"></a>00843 <span class="comment">         * probability field in the segmentation. */</span>
<a name="l00844"></a>00844         <span class="keywordflow">if</span> (search-&gt;<a class="code" href="structps__search__s.html#a721a656d0e34f7604ea8c52a1bdf14ff" title="Utterance posterior probability.">post</a> == 0)
<a name="l00845"></a>00845             search-&gt;<a class="code" href="structps__search__s.html#a721a656d0e34f7604ea8c52a1bdf14ff" title="Utterance posterior probability.">post</a> = <a class="code" href="ps__lattice_8h.html#a8c5c6ef260ab006099ab34d09b5b1d06" title="Calculate link posterior probabilities on a word graph.">ps_lattice_posterior</a>(search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>, ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>,
<a name="l00846"></a>00846                                                 ngs-&gt;<a class="code" href="structngram__search__s.html#a1e3d4b67e4b11c6c11ebe16552d53d2d" title="Acoustic score scale for posterior probabilities.">ascale</a>);
<a name="l00847"></a>00847     }
<a name="l00848"></a>00848     <span class="keywordflow">if</span> (out_score)
<a name="l00849"></a>00849         *out_score = search-&gt;<a class="code" href="structps__search__s.html#aa3020ef7bd4e56713dfe2fbad52e6e4f" title="Final link in best path.">last_link</a>-&gt;<a class="code" href="structps__latlink__s.html#a704fcfbdb57b1461325544c782289599" title="Best path score from root of DAG.">path_scr</a> + search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>-&gt;<a class="code" href="structps__lattice__s.html#aba113d4134c72d7405423c77bcc1247e" title="Acoustic score of implicit link exiting final node.">final_node_ascr</a>;
<a name="l00850"></a>00850     <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#aa3020ef7bd4e56713dfe2fbad52e6e4f" title="Final link in best path.">last_link</a>;
<a name="l00851"></a>00851 }
<a name="l00852"></a>00852 
<a name="l00853"></a>00853 <span class="keyword">static</span> <span class="keywordtype">char</span> <span class="keyword">const</span> *
<a name="l00854"></a>00854 ngram_search_hyp(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, int32 *out_score)
<a name="l00855"></a>00855 {
<a name="l00856"></a>00856     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l00857"></a>00857 
<a name="l00858"></a>00858     <span class="comment">/* Only do bestpath search if the utterance is complete. */</span>
<a name="l00859"></a>00859     <span class="keywordflow">if</span> (ngs-&gt;bestpath &amp;&amp; ngs-&gt;done) {
<a name="l00860"></a>00860         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l00861"></a>00861         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l00862"></a>00862         <span class="keywordtype">char</span> <span class="keyword">const</span> *hyp;
<a name="l00863"></a>00863         <span class="keywordtype">double</span> n_speech;
<a name="l00864"></a>00864 
<a name="l00865"></a>00865         ptmr_reset(&amp;ngs-&gt;bestpath_perf);
<a name="l00866"></a>00866         ptmr_start(&amp;ngs-&gt;bestpath_perf);
<a name="l00867"></a>00867         <span class="keywordflow">if</span> ((dag = <a class="code" href="ngram__search_8c.html#ac30e7dec4bbfeee9f5163abf4bbd1014" title="Construct a word lattice from the current hypothesis.">ngram_search_lattice</a>(search)) == NULL)
<a name="l00868"></a>00868             <span class="keywordflow">return</span> NULL;
<a name="l00869"></a>00869         <span class="keywordflow">if</span> ((link = ngram_search_bestpath(search, out_score, FALSE)) == NULL)
<a name="l00870"></a>00870             <span class="keywordflow">return</span> NULL;
<a name="l00871"></a>00871         hyp = <a class="code" href="ps__lattice_8c.html#a02b07c009d23b852bd4db54700dfac5b" title="Get hypothesis string after bestpath search.">ps_lattice_hyp</a>(dag, link);
<a name="l00872"></a>00872         ptmr_stop(&amp;ngs-&gt;bestpath_perf);
<a name="l00873"></a>00873         n_speech = (double)dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a>
<a name="l00874"></a>00874             / cmd_ln_int32_r(ps_search_config(ngs), <span class="stringliteral">&quot;-frate&quot;</span>);
<a name="l00875"></a>00875         E_INFO(<span class="stringliteral">&quot;bestpath %.2f CPU %.3f xRT\n&quot;</span>,
<a name="l00876"></a>00876                ngs-&gt;bestpath_perf.t_cpu,
<a name="l00877"></a>00877                ngs-&gt;bestpath_perf.t_cpu / n_speech);
<a name="l00878"></a>00878         E_INFO(<span class="stringliteral">&quot;bestpath %.2f wall %.3f xRT\n&quot;</span>,
<a name="l00879"></a>00879                ngs-&gt;bestpath_perf.t_elapsed,
<a name="l00880"></a>00880                ngs-&gt;bestpath_perf.t_elapsed / n_speech);
<a name="l00881"></a>00881         <span class="keywordflow">return</span> hyp;
<a name="l00882"></a>00882     }
<a name="l00883"></a>00883     <span class="keywordflow">else</span> {
<a name="l00884"></a>00884         int32 bpidx;
<a name="l00885"></a>00885 
<a name="l00886"></a>00886         <span class="comment">/* fwdtree and fwdflat use same backpointer table. */</span>
<a name="l00887"></a>00887         bpidx = <a class="code" href="ngram__search_8c.html#aa4b308f06bdf75b2f5eb0f0559f775ae" title="Find the best word exit for the current frame in the backpointer table.">ngram_search_find_exit</a>(ngs, -1, out_score);
<a name="l00888"></a>00888         <span class="keywordflow">if</span> (bpidx != NO_BP)
<a name="l00889"></a>00889             <span class="keywordflow">return</span> <a class="code" href="ngram__search_8c.html#aee393a136f8f7e8b98161e6eed7b1dd9" title="Backtrace from a given backpointer index to obtain a word hypothesis.">ngram_search_bp_hyp</a>(ngs, bpidx);
<a name="l00890"></a>00890     }
<a name="l00891"></a>00891 
<a name="l00892"></a>00892     <span class="keywordflow">return</span> NULL;
<a name="l00893"></a>00893 }
<a name="l00894"></a>00894 
<a name="l00895"></a>00895 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00896"></a>00896 ngram_search_bp2itor(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg, <span class="keywordtype">int</span> bp)
<a name="l00897"></a>00897 {
<a name="l00898"></a>00898     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)seg-&gt;<a class="code" href="structps__seg__s.html#a14168ddcb60e094dad36c7c920a79bb3" title="Search object from whence this came.">search</a>;
<a name="l00899"></a>00899     <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be, *pbe;
<a name="l00900"></a>00900 
<a name="l00901"></a>00901     be = &amp;ngs-&gt;bp_table[bp];
<a name="l00902"></a>00902     pbe = be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> == -1 ? NULL : &amp;ngs-&gt;bp_table[be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>];
<a name="l00903"></a>00903     seg-&gt;<a class="code" href="structps__seg__s.html#a97a0dc7db931c7e3f98d23d21ce27f04" title="Word string (pointer into dictionary hash)">word</a> = dict_wordstr(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>);
<a name="l00904"></a>00904     seg-&gt;<a class="code" href="structps__seg__s.html#a2043ca87b07df0cd80d0fb65c3521c04" title="End frame.">ef</a> = be-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l00905"></a>00905     seg-&gt;<a class="code" href="structps__seg__s.html#ac292e31304906addf3d49f1473df8ead" title="Start frame.">sf</a> = pbe ? pbe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> + 1 : 0;
<a name="l00906"></a>00906     seg-&gt;<a class="code" href="structps__seg__s.html#ae683244d90d0a5339930b47757778432" title="Log posterior probability.">prob</a> = 0; <span class="comment">/* Bogus value... */</span>
<a name="l00907"></a>00907     <span class="comment">/* Compute acoustic and LM scores for this segment. */</span>
<a name="l00908"></a>00908     <span class="keywordflow">if</span> (pbe == NULL) {
<a name="l00909"></a>00909         seg-&gt;<a class="code" href="structps__seg__s.html#a6f7706ec4c0d0ec8ecafaf0f29f41f4b" title="Acoustic score.">ascr</a> = be-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>;
<a name="l00910"></a>00910         seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = 0;
<a name="l00911"></a>00911         seg-&gt;<a class="code" href="structps__seg__s.html#a4d86c21f1ed2dc3eb3b1b1b37ce9bb48" title="Language model backoff.">lback</a> = 0;
<a name="l00912"></a>00912     }
<a name="l00913"></a>00913     <span class="keywordflow">else</span> {
<a name="l00914"></a>00914         int32 start_score;
<a name="l00915"></a>00915 
<a name="l00916"></a>00916         <span class="comment">/* Find ending path score of previous word. */</span>
<a name="l00917"></a>00917         start_score = <a class="code" href="ngram__search_8c.html#a25a80e488425b2bd4e24eb753c9295a5" title="Get the exit score for a backpointer entry with a given right context.">ngram_search_exit_score</a>(ngs, pbe,
<a name="l00918"></a>00918                                      dict_first_phone(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>));
<a name="l00919"></a>00919         assert(start_score <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>);
<a name="l00920"></a>00920         <span class="keywordflow">if</span> (be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> == ps_search_silence_wid(ngs)) {
<a name="l00921"></a>00921             seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = ngs-&gt;silpen;
<a name="l00922"></a>00922         }
<a name="l00923"></a>00923         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (dict_filler_word(ps_search_dict(ngs), be-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>)) {
<a name="l00924"></a>00924             seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = ngs-&gt;fillpen;
<a name="l00925"></a>00925         }
<a name="l00926"></a>00926         <span class="keywordflow">else</span> {
<a name="l00927"></a>00927             seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = ngram_tg_score(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>,
<a name="l00928"></a>00928                                        be-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>,
<a name="l00929"></a>00929                                        pbe-&gt;<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>,
<a name="l00930"></a>00930                                        pbe-&gt;<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>,
<a name="l00931"></a>00931                                        &amp;seg-&gt;<a class="code" href="structps__seg__s.html#a4d86c21f1ed2dc3eb3b1b1b37ce9bb48" title="Language model backoff.">lback</a>)&gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00932"></a>00932             seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = (int32)(seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> * seg-&gt;<a class="code" href="structps__seg__s.html#a2249c012b83c902f4f8ed8d98ded7d20" title="Language weight factor (for second-pass searches)">lwf</a>);
<a name="l00933"></a>00933         }
<a name="l00934"></a>00934         seg-&gt;<a class="code" href="structps__seg__s.html#a6f7706ec4c0d0ec8ecafaf0f29f41f4b" title="Acoustic score.">ascr</a> = be-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> - start_score - seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a>;
<a name="l00935"></a>00935     }
<a name="l00936"></a>00936 }
<a name="l00937"></a>00937 
<a name="l00938"></a>00938 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00939"></a>00939 ngram_bp_seg_free(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg)
<a name="l00940"></a>00940 {
<a name="l00941"></a>00941     <a class="code" href="structbptbl__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for backpointer table results.">bptbl_seg_t</a> *itor = (<a class="code" href="structbptbl__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for backpointer table results.">bptbl_seg_t</a> *)seg;
<a name="l00942"></a>00942     
<a name="l00943"></a>00943     ckd_free(itor-&gt;<a class="code" href="structbptbl__seg__s.html#a81e3d422fb2307c1a83e9490525dce7f" title="Sequence of backpointer IDs.">bpidx</a>);
<a name="l00944"></a>00944     ckd_free(itor);
<a name="l00945"></a>00945 }
<a name="l00946"></a>00946 
<a name="l00947"></a>00947 <span class="keyword">static</span> <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *
<a name="l00948"></a>00948 ngram_bp_seg_next(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg)
<a name="l00949"></a>00949 {
<a name="l00950"></a>00950     <a class="code" href="structbptbl__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for backpointer table results.">bptbl_seg_t</a> *itor = (<a class="code" href="structbptbl__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for backpointer table results.">bptbl_seg_t</a> *)seg;
<a name="l00951"></a>00951 
<a name="l00952"></a>00952     <span class="keywordflow">if</span> (++itor-&gt;<a class="code" href="structbptbl__seg__s.html#a1649196a2c03fb61b31624086ee998b5" title="Current position in bpidx.">cur</a> == itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a>) {
<a name="l00953"></a>00953         ngram_bp_seg_free(seg);
<a name="l00954"></a>00954         <span class="keywordflow">return</span> NULL;
<a name="l00955"></a>00955     }
<a name="l00956"></a>00956 
<a name="l00957"></a>00957     ngram_search_bp2itor(seg, itor-&gt;<a class="code" href="structbptbl__seg__s.html#a81e3d422fb2307c1a83e9490525dce7f" title="Sequence of backpointer IDs.">bpidx</a>[itor-&gt;<a class="code" href="structbptbl__seg__s.html#a1649196a2c03fb61b31624086ee998b5" title="Current position in bpidx.">cur</a>]);
<a name="l00958"></a>00958     <span class="keywordflow">return</span> seg;
<a name="l00959"></a>00959 }
<a name="l00960"></a>00960 
<a name="l00961"></a>00961 <span class="keyword">static</span> <a class="code" href="structps__segfuncs__s.html">ps_segfuncs_t</a> ngram_bp_segfuncs = {
<a name="l00962"></a>00962     <span class="comment">/* seg_next */</span> ngram_bp_seg_next,
<a name="l00963"></a>00963     <span class="comment">/* seg_free */</span> ngram_bp_seg_free
<a name="l00964"></a>00964 };
<a name="l00965"></a>00965 
<a name="l00966"></a>00966 <span class="keyword">static</span> <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *
<a name="l00967"></a>00967 ngram_search_bp_iter(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <span class="keywordtype">int</span> bpidx, float32 lwf)
<a name="l00968"></a>00968 {
<a name="l00969"></a>00969     <a class="code" href="structbptbl__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for backpointer table results.">bptbl_seg_t</a> *itor;
<a name="l00970"></a>00970     <span class="keywordtype">int</span> bp, cur;
<a name="l00971"></a>00971 
<a name="l00972"></a>00972     <span class="comment">/* Calling this an &quot;iterator&quot; is a bit of a misnomer since we have</span>
<a name="l00973"></a>00973 <span class="comment">     * to get the entire backtrace in order to produce it.  On the</span>
<a name="l00974"></a>00974 <span class="comment">     * other hand, all we actually need is the bptbl IDs, and we can</span>
<a name="l00975"></a>00975 <span class="comment">     * allocate a fixed-size array of them. */</span>
<a name="l00976"></a>00976     itor = ckd_calloc(1, <span class="keyword">sizeof</span>(*itor));
<a name="l00977"></a>00977     itor-&gt;<a class="code" href="structbptbl__seg__s.html#ac21f715b189c7e452385252bfcee47fe" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a510362a2281e374c839397c3e5488515" title="V-table of seg methods.">vt</a> = &amp;ngram_bp_segfuncs;
<a name="l00978"></a>00978     itor-&gt;<a class="code" href="structbptbl__seg__s.html#ac21f715b189c7e452385252bfcee47fe" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a14168ddcb60e094dad36c7c920a79bb3" title="Search object from whence this came.">search</a> = ps_search_base(ngs);
<a name="l00979"></a>00979     itor-&gt;<a class="code" href="structbptbl__seg__s.html#ac21f715b189c7e452385252bfcee47fe" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a2249c012b83c902f4f8ed8d98ded7d20" title="Language weight factor (for second-pass searches)">lwf</a> = lwf;
<a name="l00980"></a>00980     itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a> = 0;
<a name="l00981"></a>00981     bp = bpidx;
<a name="l00982"></a>00982     <span class="keywordflow">while</span> (bp != NO_BP) {
<a name="l00983"></a>00983         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be = &amp;ngs-&gt;bp_table[bp];
<a name="l00984"></a>00984         bp = be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00985"></a>00985         ++itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a>;
<a name="l00986"></a>00986     }
<a name="l00987"></a>00987     <span class="keywordflow">if</span> (itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a> == 0) {
<a name="l00988"></a>00988         ckd_free(itor);
<a name="l00989"></a>00989         <span class="keywordflow">return</span> NULL;
<a name="l00990"></a>00990     }
<a name="l00991"></a>00991     itor-&gt;<a class="code" href="structbptbl__seg__s.html#a81e3d422fb2307c1a83e9490525dce7f" title="Sequence of backpointer IDs.">bpidx</a> = ckd_calloc(itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a>, <span class="keyword">sizeof</span>(*itor-&gt;<a class="code" href="structbptbl__seg__s.html#a81e3d422fb2307c1a83e9490525dce7f" title="Sequence of backpointer IDs.">bpidx</a>));
<a name="l00992"></a>00992     cur = itor-&gt;<a class="code" href="structbptbl__seg__s.html#a8d1f0aa7dd09e2d6321a00b68ab6a051" title="Number of backpointer IDs.">n_bpidx</a> - 1;
<a name="l00993"></a>00993     bp = bpidx;
<a name="l00994"></a>00994     <span class="keywordflow">while</span> (bp != NO_BP) {
<a name="l00995"></a>00995         <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *be = &amp;ngs-&gt;bp_table[bp];
<a name="l00996"></a>00996         itor-&gt;<a class="code" href="structbptbl__seg__s.html#a81e3d422fb2307c1a83e9490525dce7f" title="Sequence of backpointer IDs.">bpidx</a>[cur] = bp;
<a name="l00997"></a>00997         bp = be-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>;
<a name="l00998"></a>00998         --cur;
<a name="l00999"></a>00999     }
<a name="l01000"></a>01000 
<a name="l01001"></a>01001     <span class="comment">/* Fill in relevant fields for first element. */</span>
<a name="l01002"></a>01002     ngram_search_bp2itor((<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *)itor, itor-&gt;bpidx[0]);
<a name="l01003"></a>01003 
<a name="l01004"></a>01004     <span class="keywordflow">return</span> (<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *)itor;
<a name="l01005"></a>01005 }
<a name="l01006"></a>01006 
<a name="l01007"></a>01007 <span class="keyword">static</span> <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *
<a name="l01008"></a>01008 ngram_search_seg_iter(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search, int32 *out_score)
<a name="l01009"></a>01009 {
<a name="l01010"></a>01010     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l01011"></a>01011 
<a name="l01012"></a>01012     <span class="comment">/* Only do bestpath search if the utterance is done. */</span>
<a name="l01013"></a>01013     <span class="keywordflow">if</span> (ngs-&gt;bestpath &amp;&amp; ngs-&gt;done) {
<a name="l01014"></a>01014         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01015"></a>01015         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l01016"></a>01016         <span class="keywordtype">double</span> n_speech;
<a name="l01017"></a>01017         <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *itor;
<a name="l01018"></a>01018 
<a name="l01019"></a>01019         ptmr_reset(&amp;ngs-&gt;bestpath_perf);
<a name="l01020"></a>01020         ptmr_start(&amp;ngs-&gt;bestpath_perf);
<a name="l01021"></a>01021         <span class="keywordflow">if</span> ((dag = <a class="code" href="ngram__search_8c.html#ac30e7dec4bbfeee9f5163abf4bbd1014" title="Construct a word lattice from the current hypothesis.">ngram_search_lattice</a>(search)) == NULL)
<a name="l01022"></a>01022             <span class="keywordflow">return</span> NULL;
<a name="l01023"></a>01023         <span class="keywordflow">if</span> ((link = ngram_search_bestpath(search, out_score, TRUE)) == NULL)
<a name="l01024"></a>01024             <span class="keywordflow">return</span> NULL;
<a name="l01025"></a>01025         itor = <a class="code" href="ps__lattice_8c.html#afedbc5558c18f7d029e84a4e27e38187" title="Get hypothesis segmentation iterator after bestpath search.">ps_lattice_seg_iter</a>(dag, link,
<a name="l01026"></a>01026                                    ngs-&gt;bestpath_fwdtree_lw_ratio);
<a name="l01027"></a>01027         ptmr_stop(&amp;ngs-&gt;bestpath_perf);
<a name="l01028"></a>01028         n_speech = (double)dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a>
<a name="l01029"></a>01029             / cmd_ln_int32_r(ps_search_config(ngs), <span class="stringliteral">&quot;-frate&quot;</span>);
<a name="l01030"></a>01030         E_INFO(<span class="stringliteral">&quot;bestpath %.2f CPU %.3f xRT\n&quot;</span>,
<a name="l01031"></a>01031                ngs-&gt;bestpath_perf.t_cpu,
<a name="l01032"></a>01032                ngs-&gt;bestpath_perf.t_cpu / n_speech);
<a name="l01033"></a>01033         E_INFO(<span class="stringliteral">&quot;bestpath %.2f wall %.3f xRT\n&quot;</span>,
<a name="l01034"></a>01034                ngs-&gt;bestpath_perf.t_elapsed,
<a name="l01035"></a>01035                ngs-&gt;bestpath_perf.t_elapsed / n_speech);
<a name="l01036"></a>01036         <span class="keywordflow">return</span> itor;
<a name="l01037"></a>01037     }
<a name="l01038"></a>01038     <span class="keywordflow">else</span> {
<a name="l01039"></a>01039         int32 bpidx;
<a name="l01040"></a>01040 
<a name="l01041"></a>01041         <span class="comment">/* fwdtree and fwdflat use same backpointer table. */</span>
<a name="l01042"></a>01042         bpidx = <a class="code" href="ngram__search_8c.html#aa4b308f06bdf75b2f5eb0f0559f775ae" title="Find the best word exit for the current frame in the backpointer table.">ngram_search_find_exit</a>(ngs, -1, out_score);
<a name="l01043"></a>01043         <span class="keywordflow">return</span> ngram_search_bp_iter(ngs, bpidx,
<a name="l01044"></a>01044                                     <span class="comment">/* but different language weights... */</span>
<a name="l01045"></a>01045                                     (ngs-&gt;done &amp;&amp; ngs-&gt;fwdflat)
<a name="l01046"></a>01046                                     ? ngs-&gt;fwdflat_fwdtree_lw_ratio : 1.0);
<a name="l01047"></a>01047     }
<a name="l01048"></a>01048 
<a name="l01049"></a>01049     <span class="keywordflow">return</span> NULL;
<a name="l01050"></a>01050 }
<a name="l01051"></a>01051 
<a name="l01052"></a>01052 <span class="keyword">static</span> int32
<a name="l01053"></a>01053 ngram_search_prob(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l01054"></a>01054 {
<a name="l01055"></a>01055     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l01056"></a>01056 
<a name="l01057"></a>01057     <span class="comment">/* Only do bestpath search if the utterance is done. */</span>
<a name="l01058"></a>01058     <span class="keywordflow">if</span> (ngs-&gt;bestpath &amp;&amp; ngs-&gt;done) {
<a name="l01059"></a>01059         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01060"></a>01060         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l01061"></a>01061 
<a name="l01062"></a>01062         <span class="keywordflow">if</span> ((dag = <a class="code" href="ngram__search_8c.html#ac30e7dec4bbfeee9f5163abf4bbd1014" title="Construct a word lattice from the current hypothesis.">ngram_search_lattice</a>(search)) == NULL)
<a name="l01063"></a>01063             <span class="keywordflow">return</span> 0;
<a name="l01064"></a>01064         <span class="keywordflow">if</span> ((link = ngram_search_bestpath(search, NULL, TRUE)) == NULL)
<a name="l01065"></a>01065             <span class="keywordflow">return</span> 0;
<a name="l01066"></a>01066         <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#a721a656d0e34f7604ea8c52a1bdf14ff" title="Utterance posterior probability.">post</a>;
<a name="l01067"></a>01067     }
<a name="l01068"></a>01068     <span class="keywordflow">else</span> {
<a name="l01069"></a>01069         <span class="comment">/* FIXME: Give some kind of good estimate here, eventually. */</span>
<a name="l01070"></a>01070         <span class="keywordflow">return</span> 0;
<a name="l01071"></a>01071     }
<a name="l01072"></a>01072 }
<a name="l01073"></a>01073 
<a name="l01074"></a>01074 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l01075"></a>01075 create_dag_nodes(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag)
<a name="l01076"></a>01076 {
<a name="l01077"></a>01077     <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *bp_ptr;
<a name="l01078"></a>01078     int32 i;
<a name="l01079"></a>01079 
<a name="l01080"></a>01080     <span class="keywordflow">for</span> (i = 0, bp_ptr = ngs-&gt;bp_table; i &lt; ngs-&gt;bpidx; ++i, ++bp_ptr) {
<a name="l01081"></a>01081         int32 sf, ef, wid;
<a name="l01082"></a>01082         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01083"></a>01083 
<a name="l01084"></a>01084         <span class="comment">/* Skip invalid backpointers (these result from -maxwpf pruning) */</span>
<a name="l01085"></a>01085         <span class="keywordflow">if</span> (!bp_ptr-&gt;<a class="code" href="structbptbl__s.html#a4948439666e1e2204a6d1c6d9cfd1cd0" title="For absolute pruning.">valid</a>)
<a name="l01086"></a>01086             <span class="keywordflow">continue</span>;
<a name="l01087"></a>01087 
<a name="l01088"></a>01088         sf = (bp_ptr-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a> &lt; 0) ? 0 : ngs-&gt;bp_table[bp_ptr-&gt;<a class="code" href="structbptbl__s.html#a4ca45ebc4a1ac18fc0596195e7e03bc8" title="Back Pointer.">bp</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> + 1;
<a name="l01089"></a>01089         ef = bp_ptr-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01090"></a>01090         wid = bp_ptr-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>;
<a name="l01091"></a>01091 
<a name="l01092"></a>01092         assert(ef &lt; dag-&gt;n_frames);
<a name="l01093"></a>01093         <span class="comment">/* Skip non-final &lt;/s&gt; entries. */</span>
<a name="l01094"></a>01094         <span class="keywordflow">if</span> ((wid == ps_search_finish_wid(ngs)) &amp;&amp; (ef &lt; dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a> - 1))
<a name="l01095"></a>01095             <span class="keywordflow">continue</span>;
<a name="l01096"></a>01096 
<a name="l01097"></a>01097         <span class="comment">/* Skip if word not in LM */</span>
<a name="l01098"></a>01098         <span class="keywordflow">if</span> ((!dict_filler_word(ps_search_dict(ngs), wid))
<a name="l01099"></a>01099             &amp;&amp; (!ngram_model_set_known_wid(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>,
<a name="l01100"></a>01100                                            dict_basewid(ps_search_dict(ngs), wid))))
<a name="l01101"></a>01101             <span class="keywordflow">continue</span>;
<a name="l01102"></a>01102 
<a name="l01103"></a>01103         <span class="comment">/* See if bptbl entry &lt;wid,sf&gt; already in lattice */</span>
<a name="l01104"></a>01104         <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01105"></a>01105             <span class="keywordflow">if</span> ((node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> == wid) &amp;&amp; (node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == sf))
<a name="l01106"></a>01106                 <span class="keywordflow">break</span>;
<a name="l01107"></a>01107         }
<a name="l01108"></a>01108 
<a name="l01109"></a>01109         <span class="comment">/* For the moment, store bptbl indices in node.{fef,lef} */</span>
<a name="l01110"></a>01110         <span class="keywordflow">if</span> (node)
<a name="l01111"></a>01111             node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> = i;
<a name="l01112"></a>01112         <span class="keywordflow">else</span> {
<a name="l01113"></a>01113             <span class="comment">/* New node; link to head of list */</span>
<a name="l01114"></a>01114             node = listelem_malloc(dag-&gt;<a class="code" href="structps__lattice__s.html#a14e4e87550647d5119cd1cc48ff4f3f1" title="Node allocator for this DAG.">latnode_alloc</a>);
<a name="l01115"></a>01115             node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> = wid;
<a name="l01116"></a>01116             node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> = sf; <span class="comment">/* This is a frame index. */</span>
<a name="l01117"></a>01117             node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a> = node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> = i; <span class="comment">/* These are backpointer indices (argh) */</span>
<a name="l01118"></a>01118             node-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = FALSE;
<a name="l01119"></a>01119             node-&gt;<a class="code" href="structps__latnode__s.html#a051a7eed31e29dd75151d1b34cc4eefa" title="Links into this node.">entries</a> = NULL;
<a name="l01120"></a>01120             node-&gt;<a class="code" href="structps__latnode__s.html#a5232eefbc6e800b77e7a3c8ee3f4135d" title="Links out of this node.">exits</a> = NULL;
<a name="l01121"></a>01121 
<a name="l01122"></a>01122             <span class="comment">/* NOTE: This creates the list of nodes in reverse</span>
<a name="l01123"></a>01123 <span class="comment">             * topological order, i.e. a node always precedes its</span>
<a name="l01124"></a>01124 <span class="comment">             * antecedents in this list. */</span>
<a name="l01125"></a>01125             node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a> = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>;
<a name="l01126"></a>01126             dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a> = node;
<a name="l01127"></a>01127             ++dag-&gt;<a class="code" href="structps__lattice__s.html#ab3690a8d16e3fa8a3b0dd3aa8277b653" title="Number of nodes in this lattice.">n_nodes</a>;
<a name="l01128"></a>01128         }
<a name="l01129"></a>01129     }
<a name="l01130"></a>01130 }
<a name="l01131"></a>01131 
<a name="l01132"></a>01132 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01133"></a>01133 find_start_node(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag)
<a name="l01134"></a>01134 {
<a name="l01135"></a>01135     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01136"></a>01136 
<a name="l01137"></a>01137     <span class="comment">/* Find start node &lt;s&gt;.0 */</span>
<a name="l01138"></a>01138     <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01139"></a>01139         <span class="keywordflow">if</span> ((node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> == ps_search_start_wid(ngs)) &amp;&amp; (node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == 0))
<a name="l01140"></a>01140             <span class="keywordflow">break</span>;
<a name="l01141"></a>01141     }
<a name="l01142"></a>01142     <span class="keywordflow">if</span> (!node) {
<a name="l01143"></a>01143         <span class="comment">/* This is probably impossible. */</span>
<a name="l01144"></a>01144         E_ERROR(<span class="stringliteral">&quot;Couldn&#39;t find &lt;s&gt; in first frame\n&quot;</span>);
<a name="l01145"></a>01145         <span class="keywordflow">return</span> NULL;
<a name="l01146"></a>01146     }
<a name="l01147"></a>01147     <span class="keywordflow">return</span> node;
<a name="l01148"></a>01148 }
<a name="l01149"></a>01149 
<a name="l01150"></a>01150 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01151"></a>01151 find_end_node(<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs, <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag, float32 lwf)
<a name="l01152"></a>01152 {
<a name="l01153"></a>01153     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01154"></a>01154     int32 ef, bestbp, bp, bestscore;
<a name="l01155"></a>01155 
<a name="l01156"></a>01156     <span class="comment">/* Find final node &lt;/s&gt;.last_frame; nothing can follow this node */</span>
<a name="l01157"></a>01157     <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01158"></a>01158         int32 lef = ngs-&gt;bp_table[node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01159"></a>01159         <span class="keywordflow">if</span> ((node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> == ps_search_finish_wid(ngs))
<a name="l01160"></a>01160             &amp;&amp; (lef == dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a> - 1))
<a name="l01161"></a>01161             <span class="keywordflow">break</span>;
<a name="l01162"></a>01162     }
<a name="l01163"></a>01163     <span class="keywordflow">if</span> (node != NULL)
<a name="l01164"></a>01164         <span class="keywordflow">return</span> node;
<a name="l01165"></a>01165 
<a name="l01166"></a>01166     <span class="comment">/* It is quite likely that no &lt;/s&gt; exited in the last frame.  So,</span>
<a name="l01167"></a>01167 <span class="comment">     * find the node corresponding to the best exit. */</span>
<a name="l01168"></a>01168     <span class="comment">/* Find the last frame containing a word exit. */</span>
<a name="l01169"></a>01169     <span class="keywordflow">for</span> (ef = dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a> - 1;
<a name="l01170"></a>01170          ef &gt;= 0 &amp;&amp; ngs-&gt;bp_table_idx[ef] == ngs-&gt;bpidx;
<a name="l01171"></a>01171          --ef);
<a name="l01172"></a>01172     <span class="keywordflow">if</span> (ef &lt; 0) {
<a name="l01173"></a>01173         E_ERROR(<span class="stringliteral">&quot;Empty backpointer table: can not build DAG.\n&quot;</span>);
<a name="l01174"></a>01174         <span class="keywordflow">return</span> NULL;
<a name="l01175"></a>01175     }
<a name="l01176"></a>01176 
<a name="l01177"></a>01177     <span class="comment">/* Find best word exit in that frame. */</span>
<a name="l01178"></a>01178     bestscore = <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>;
<a name="l01179"></a>01179     bestbp = NO_BP;
<a name="l01180"></a>01180     <span class="keywordflow">for</span> (bp = ngs-&gt;bp_table_idx[ef]; bp &lt; ngs-&gt;bp_table_idx[ef + 1]; ++bp) {
<a name="l01181"></a>01181         int32 n_used, l_scr, wid, prev_wid;
<a name="l01182"></a>01182         wid = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a91247e4f807cf780afe8f5ac45e720b8" title="wid of this or latest predecessor real word">real_wid</a>;
<a name="l01183"></a>01183         prev_wid = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#a83784e3b0121bc365d485151ab277920" title="wid of second-last real word">prev_real_wid</a>;
<a name="l01184"></a>01184         <span class="comment">/* Always prefer &lt;/s&gt;, of which there will only be one per frame. */</span>
<a name="l01185"></a>01185         <span class="keywordflow">if</span> (wid == ps_search_finish_wid(ngs)) {
<a name="l01186"></a>01186             bestbp = bp;
<a name="l01187"></a>01187             <span class="keywordflow">break</span>;
<a name="l01188"></a>01188         }
<a name="l01189"></a>01189         l_scr = ngram_tg_score(ngs-&gt;<a class="code" href="structngram__search__s.html#a6127a6d8fb53832e67456c11aa6ad9c4" title="Set of language models.">lmset</a>, ps_search_finish_wid(ngs),
<a name="l01190"></a>01190                                wid, prev_wid, &amp;n_used) &gt;&gt;<a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l01191"></a>01191         l_scr = l_scr * lwf;
<a name="l01192"></a>01192         <span class="keywordflow">if</span> (ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> + l_scr <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> bestscore) {
<a name="l01193"></a>01193             bestscore = ngs-&gt;bp_table[bp].<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a> + l_scr;
<a name="l01194"></a>01194             bestbp = bp;
<a name="l01195"></a>01195         }
<a name="l01196"></a>01196     }
<a name="l01197"></a>01197     <span class="keywordflow">if</span> (bestbp == NO_BP) {
<a name="l01198"></a>01198         E_ERROR(<span class="stringliteral">&quot;No word exits found in last frame (%d), assuming no recognition\n&quot;</span>, ef);
<a name="l01199"></a>01199         <span class="keywordflow">return</span> NULL;
<a name="l01200"></a>01200     }
<a name="l01201"></a>01201     E_INFO(<span class="stringliteral">&quot;&lt;/s&gt; not found in last frame, using %s.%d instead\n&quot;</span>,
<a name="l01202"></a>01202            dict_basestr(ps_search_dict(ngs), ngs-&gt;bp_table[bestbp].<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>), ef);
<a name="l01203"></a>01203 
<a name="l01204"></a>01204     <span class="comment">/* Now find the node that corresponds to it. */</span>
<a name="l01205"></a>01205     <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01206"></a>01206         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> == bestbp)
<a name="l01207"></a>01207             <span class="keywordflow">return</span> node;
<a name="l01208"></a>01208     }
<a name="l01209"></a>01209 
<a name="l01210"></a>01210     <span class="comment">/* FIXME: This seems to happen a lot! */</span>
<a name="l01211"></a>01211     E_ERROR(<span class="stringliteral">&quot;Failed to find DAG node corresponding to %s\n&quot;</span>,
<a name="l01212"></a>01212            dict_basestr(ps_search_dict(ngs), ngs-&gt;bp_table[bestbp].<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a>));
<a name="l01213"></a>01213     <span class="keywordflow">return</span> NULL;
<a name="l01214"></a>01214 }
<a name="l01215"></a>01215 
<a name="l01216"></a>01216 <span class="comment">/*</span>
<a name="l01217"></a>01217 <span class="comment"> * Build lattice from bptable.</span>
<a name="l01218"></a>01218 <span class="comment"> */</span>
<a name="l01219"></a>01219 <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *
<a name="l01220"></a><a class="code" href="ngram__search_8h.html#ac30e7dec4bbfeee9f5163abf4bbd1014">01220</a> <a class="code" href="ngram__search_8c.html#ac30e7dec4bbfeee9f5163abf4bbd1014" title="Construct a word lattice from the current hypothesis.">ngram_search_lattice</a>(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l01221"></a>01221 {
<a name="l01222"></a>01222     int32 i, score, ascr, lscr;
<a name="l01223"></a>01223     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node, *from, *to;
<a name="l01224"></a>01224     <a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *ngs;
<a name="l01225"></a>01225     <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01226"></a>01226     <span class="keywordtype">int</span> min_endfr, nlink;
<a name="l01227"></a>01227     <span class="keywordtype">float</span> lwf;
<a name="l01228"></a>01228 
<a name="l01229"></a>01229     ngs = (<a class="code" href="structngram__search__s.html" title="N-Gram search module structure.">ngram_search_t</a> *)search;
<a name="l01230"></a>01230     min_endfr = cmd_ln_int32_r(ps_search_config(search), <span class="stringliteral">&quot;-min_endfr&quot;</span>);
<a name="l01231"></a>01231 
<a name="l01232"></a>01232     <span class="comment">/* If the best score is WORST_SCORE or worse, there is no way to</span>
<a name="l01233"></a>01233 <span class="comment">     * make a lattice. */</span>
<a name="l01234"></a>01234     <span class="keywordflow">if</span> (ngs-&gt;<a class="code" href="structngram__search__s.html#a150d99157e2f37a6f0dbb4b02682d9c3" title="Best Viterbi path score.">best_score</a> == <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a> || ngs-&gt;<a class="code" href="structngram__search__s.html#a150d99157e2f37a6f0dbb4b02682d9c3" title="Best Viterbi path score.">best_score</a> <a class="code" href="hmm_8h.html#aa930fb8fb6fce7f34bcf4018b81d7066" title="Is one score worse than another?">WORSE_THAN</a> <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>)
<a name="l01235"></a>01235         <span class="keywordflow">return</span> NULL;
<a name="l01236"></a>01236 
<a name="l01237"></a>01237     <span class="comment">/* Check to see if a lattice has previously been created over the</span>
<a name="l01238"></a>01238 <span class="comment">     * same number of frames, and reuse it if so. */</span>
<a name="l01239"></a>01239     <span class="keywordflow">if</span> (search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a> &amp;&amp; search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a> == ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a>)
<a name="l01240"></a>01240         <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>;
<a name="l01241"></a>01241 
<a name="l01242"></a>01242     <span class="comment">/* Nope, create a new one. */</span>
<a name="l01243"></a>01243     <a class="code" href="ps__lattice_8h.html#a3f90e846bde47cd1acdff165b92f5c22" title="Free a lattice.">ps_lattice_free</a>(search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a>);
<a name="l01244"></a>01244     search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a> = NULL;
<a name="l01245"></a>01245     dag = <a class="code" href="ps__lattice_8c.html#a606f6ee0fd569dd5829d7f84ae7e61bd" title="Construct an empty word graph with reference to a search structure.">ps_lattice_init_search</a>(search, ngs-&gt;<a class="code" href="structngram__search__s.html#a5255e56d28c239a4e1d9b1721e8a2f8d" title="Number of frames actually present.">n_frame</a>);
<a name="l01246"></a>01246     <span class="comment">/* Compute these such that they agree with the fwdtree language weight. */</span>
<a name="l01247"></a>01247     lwf = ngs-&gt;fwdflat ? ngs-&gt;fwdflat_fwdtree_lw_ratio : 1.0;
<a name="l01248"></a>01248     create_dag_nodes(ngs, dag);
<a name="l01249"></a>01249     <span class="keywordflow">if</span> ((dag-&gt;<a class="code" href="structps__lattice__s.html#a5d936695a3813e117d20b585d48db8fe" title="Starting node.">start</a> = find_start_node(ngs, dag)) == NULL)
<a name="l01250"></a>01250         <span class="keywordflow">goto</span> error_out;
<a name="l01251"></a>01251     <span class="keywordflow">if</span> ((dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a> = find_end_node(ngs, dag, ngs-&gt;bestpath_fwdtree_lw_ratio)) == NULL)
<a name="l01252"></a>01252         <span class="keywordflow">goto</span> error_out;
<a name="l01253"></a>01253     E_INFO(<span class="stringliteral">&quot;lattice start node %s.%d end node %s.%d\n&quot;</span>,
<a name="l01254"></a>01254            dict_wordstr(search-&gt;<a class="code" href="structps__search__s.html#a918f243fa966e72c47f697fb9e60089d" title="Pronunciation dictionary.">dict</a>, dag-&gt;<a class="code" href="structps__lattice__s.html#a5d936695a3813e117d20b585d48db8fe" title="Starting node.">start</a>-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>), dag-&gt;<a class="code" href="structps__lattice__s.html#a5d936695a3813e117d20b585d48db8fe" title="Starting node.">start</a>-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a>,
<a name="l01255"></a>01255            dict_wordstr(search-&gt;<a class="code" href="structps__search__s.html#a918f243fa966e72c47f697fb9e60089d" title="Pronunciation dictionary.">dict</a>, dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>), dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a>);
<a name="l01256"></a>01256 
<a name="l01257"></a>01257     ngram_compute_seg_score(ngs, ngs-&gt;bp_table + dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>, lwf,
<a name="l01258"></a>01258                             &amp;dag-&gt;<a class="code" href="structps__lattice__s.html#aba113d4134c72d7405423c77bcc1247e" title="Acoustic score of implicit link exiting final node.">final_node_ascr</a>, &amp;lscr);
<a name="l01259"></a>01259 
<a name="l01260"></a>01260     <span class="comment">/*</span>
<a name="l01261"></a>01261 <span class="comment">     * At this point, dag-&gt;nodes is ordered such that nodes earlier in</span>
<a name="l01262"></a>01262 <span class="comment">     * the list can follow (in time) those later in the list, but not</span>
<a name="l01263"></a>01263 <span class="comment">     * vice versa (see above - also note that adjacency is purely</span>
<a name="l01264"></a>01264 <span class="comment">     * determined by time which is why we can make this claim).  Now</span>
<a name="l01265"></a>01265 <span class="comment">     * create precedence links and simultanesously mark all nodes that</span>
<a name="l01266"></a>01266 <span class="comment">     * can reach dag-&gt;end.  (All nodes are reached from dag-&gt;start</span>
<a name="l01267"></a>01267 <span class="comment">     * simply by definition - they were created that way).</span>
<a name="l01268"></a>01268 <span class="comment">     *</span>
<a name="l01269"></a>01269 <span class="comment">     * Note that this also means that any nodes before dag-&gt;end in the</span>
<a name="l01270"></a>01270 <span class="comment">     * list can be discarded, meaning that dag-&gt;end will always be</span>
<a name="l01271"></a>01271 <span class="comment">     * equal to dag-&gt;nodes (FIXME: except when loading from a file but</span>
<a name="l01272"></a>01272 <span class="comment">     * we can fix that...)</span>
<a name="l01273"></a>01273 <span class="comment">     */</span>
<a name="l01274"></a>01274     i = 0;
<a name="l01275"></a>01275     <span class="keywordflow">while</span> (dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a> &amp;&amp; dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a> != dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>) {
<a name="l01276"></a>01276         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *next = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>;
<a name="l01277"></a>01277         listelem_free(dag-&gt;<a class="code" href="structps__lattice__s.html#a14e4e87550647d5119cd1cc48ff4f3f1" title="Node allocator for this DAG.">latnode_alloc</a>, dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>);
<a name="l01278"></a>01278         dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a> = next;
<a name="l01279"></a>01279         ++i;
<a name="l01280"></a>01280     }
<a name="l01281"></a>01281     E_INFO(<span class="stringliteral">&quot;Eliminated %d nodes before end node\n&quot;</span>, i);
<a name="l01282"></a>01282     dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = TRUE;
<a name="l01283"></a>01283     nlink = 0;
<a name="l01284"></a>01284     <span class="keywordflow">for</span> (to = dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>; to; to = to-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01285"></a>01285         <span class="keywordtype">int</span> fef, lef;
<a name="l01286"></a>01286 
<a name="l01287"></a>01287         <span class="comment">/* Skip if not reachable; it will never be reachable from dag-&gt;end */</span>
<a name="l01288"></a>01288         <span class="keywordflow">if</span> (!to-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a>)
<a name="l01289"></a>01289             <span class="keywordflow">continue</span>;
<a name="l01290"></a>01290 
<a name="l01291"></a>01291         <span class="comment">/* Prune nodes with too few endpoints - heuristic</span>
<a name="l01292"></a>01292 <span class="comment">           borrowed from Sphinx3 */</span>
<a name="l01293"></a>01293         fef = ngs-&gt;bp_table[to-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01294"></a>01294         lef = ngs-&gt;bp_table[to-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01295"></a>01295         <span class="keywordflow">if</span> (to != dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a> &amp;&amp; lef - fef &lt; min_endfr) {
<a name="l01296"></a>01296             to-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = FALSE;
<a name="l01297"></a>01297             <span class="keywordflow">continue</span>;
<a name="l01298"></a>01298         }
<a name="l01299"></a>01299 
<a name="l01300"></a>01300         <span class="comment">/* Find predecessors of to : from-&gt;fef+1 &lt;= to-&gt;sf &lt;= from-&gt;lef+1 */</span>
<a name="l01301"></a>01301         <span class="keywordflow">for</span> (from = to-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>; from; from = from-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01302"></a>01302             <a class="code" href="structbptbl__s.html" title="Back pointer table (forward pass lattice; actually a tree)">bptbl_t</a> *from_bpe;
<a name="l01303"></a>01303 
<a name="l01304"></a>01304             fef = ngs-&gt;bp_table[from-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01305"></a>01305             lef = ngs-&gt;bp_table[from-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01306"></a>01306 
<a name="l01307"></a>01307             <span class="keywordflow">if</span> ((to-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> &lt;= fef) || (to-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> &gt; lef + 1))
<a name="l01308"></a>01308                 <span class="keywordflow">continue</span>;
<a name="l01309"></a>01309             <span class="keywordflow">if</span> (lef - fef &lt; min_endfr) {
<a name="l01310"></a>01310                 assert(!from-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a>);
<a name="l01311"></a>01311                 <span class="keywordflow">continue</span>;
<a name="l01312"></a>01312             }
<a name="l01313"></a>01313 
<a name="l01314"></a>01314             <span class="comment">/* Find bptable entry for &quot;from&quot; that exactly precedes &quot;to&quot; */</span>
<a name="l01315"></a>01315             i = from-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>;
<a name="l01316"></a>01316             from_bpe = ngs-&gt;bp_table + i;
<a name="l01317"></a>01317             <span class="keywordflow">for</span> (; i &lt;= from-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>; i++, from_bpe++) {
<a name="l01318"></a>01318                 <span class="keywordflow">if</span> (from_bpe-&gt;<a class="code" href="structbptbl__s.html#a143ff0891fafd471000df7c73123b8a7" title="Word index.">wid</a> != from-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>)
<a name="l01319"></a>01319                     <span class="keywordflow">continue</span>;
<a name="l01320"></a>01320                 <span class="keywordflow">if</span> (from_bpe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> &gt;= to-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> - 1)
<a name="l01321"></a>01321                     <span class="keywordflow">break</span>;
<a name="l01322"></a>01322             }
<a name="l01323"></a>01323 
<a name="l01324"></a>01324             <span class="keywordflow">if</span> ((i &gt; from-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>) || (from_bpe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a> != to-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> - 1))
<a name="l01325"></a>01325                 <span class="keywordflow">continue</span>;
<a name="l01326"></a>01326 
<a name="l01327"></a>01327             <span class="comment">/* Find acoustic score from.sf-&gt;to.sf-1 with right context = to */</span>
<a name="l01328"></a>01328             <span class="comment">/* This gives us from_bpe&#39;s best acoustic score. */</span>
<a name="l01329"></a>01329             ngram_compute_seg_score(ngs, from_bpe, lwf,
<a name="l01330"></a>01330                                     &amp;ascr, &amp;lscr);
<a name="l01331"></a>01331             <span class="comment">/* Now find the exact path score for from-&gt;to, including</span>
<a name="l01332"></a>01332 <span class="comment">             * the appropriate final triphone.  In fact this might not</span>
<a name="l01333"></a>01333 <span class="comment">             * exist. */</span>
<a name="l01334"></a>01334             score = <a class="code" href="ngram__search_8c.html#a25a80e488425b2bd4e24eb753c9295a5" title="Get the exit score for a backpointer entry with a given right context.">ngram_search_exit_score</a>(ngs, from_bpe,
<a name="l01335"></a>01335                                             dict_first_phone(ps_search_dict(ngs), to-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>));
<a name="l01336"></a>01336             <span class="comment">/* Does not exist.  Can&#39;t create a link here. */</span>
<a name="l01337"></a>01337             <span class="keywordflow">if</span> (score == WORST_SCORE)
<a name="l01338"></a>01338                 <span class="keywordflow">continue</span>;
<a name="l01339"></a>01339             <span class="comment">/* Adjust the arc score to match the correct triphone. */</span>
<a name="l01340"></a>01340             <span class="keywordflow">else</span>
<a name="l01341"></a>01341                 score = ascr + (score - from_bpe-&gt;<a class="code" href="structbptbl__s.html#aa5643c0c19ce4d39d51ddf7376f4d508" title="Score (best among all right contexts)">score</a>);
<a name="l01342"></a>01342             <span class="keywordflow">if</span> (score <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> 0) {
<a name="l01343"></a>01343                 <span class="comment">/* Scores must be negative, or Bad Things will happen.</span>
<a name="l01344"></a>01344 <span class="comment">                   In general, they are, except in corner cases</span>
<a name="l01345"></a>01345 <span class="comment">                   involving filler words.  We don&#39;t want to throw any</span>
<a name="l01346"></a>01346 <span class="comment">                   links away so we&#39;ll keep these, but with some</span>
<a name="l01347"></a>01347 <span class="comment">                   arbitrarily improbable but recognizable score. */</span>
<a name="l01348"></a>01348                 <a class="code" href="ps__lattice_8h.html#a4aaae70904361b23a78cdcb632c298c4" title="Create a directed link between &amp;quot;from&amp;quot; and &amp;quot;to&amp;quot; nodes, but if a link already exist...">ps_lattice_link</a>(dag, from, to, -424242, from_bpe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>);
<a name="l01349"></a>01349                 ++nlink;
<a name="l01350"></a>01350                 from-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = TRUE;
<a name="l01351"></a>01351             }
<a name="l01352"></a>01352             <span class="keywordflow">else</span> <span class="keywordflow">if</span> (score BETTER_THAN WORST_SCORE) {
<a name="l01353"></a>01353                 <a class="code" href="ps__lattice_8h.html#a4aaae70904361b23a78cdcb632c298c4" title="Create a directed link between &amp;quot;from&amp;quot; and &amp;quot;to&amp;quot; nodes, but if a link already exist...">ps_lattice_link</a>(dag, from, to, score, from_bpe-&gt;<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>);
<a name="l01354"></a>01354                 ++nlink;
<a name="l01355"></a>01355                 from-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = TRUE;
<a name="l01356"></a>01356             }
<a name="l01357"></a>01357         }
<a name="l01358"></a>01358     }
<a name="l01359"></a>01359 
<a name="l01360"></a>01360     <span class="comment">/* There must be at least one path between dag-&gt;start and dag-&gt;end */</span>
<a name="l01361"></a>01361     <span class="keywordflow">if</span> (!dag-&gt;<a class="code" href="structps__lattice__s.html#a5d936695a3813e117d20b585d48db8fe" title="Starting node.">start</a>-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a>) {
<a name="l01362"></a>01362         E_ERROR(<span class="stringliteral">&quot;End node of lattice isolated; unreachable\n&quot;</span>);
<a name="l01363"></a>01363         <span class="keywordflow">goto</span> error_out;
<a name="l01364"></a>01364     }
<a name="l01365"></a>01365 
<a name="l01366"></a>01366     <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01367"></a>01367         <span class="comment">/* Change node-&gt;{fef,lef} from bptbl indices to frames. */</span>
<a name="l01368"></a>01368         node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a> = ngs-&gt;bp_table[node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01369"></a>01369         node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> = ngs-&gt;bp_table[node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>].<a class="code" href="structbptbl__s.html#ad1f5831762cf337974ce243902364f42" title="start or end frame">frame</a>;
<a name="l01370"></a>01370         <span class="comment">/* Find base wid for nodes. */</span>
<a name="l01371"></a>01371         node-&gt;<a class="code" href="structps__latnode__s.html#ae3b3dc7d14347e6380859c74b9a02589" title="Dictionary base word id.">basewid</a> = dict_basewid(search-&gt;<a class="code" href="structps__search__s.html#a918f243fa966e72c47f697fb9e60089d" title="Pronunciation dictionary.">dict</a>, node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>);
<a name="l01372"></a>01372     }
<a name="l01373"></a>01373 
<a name="l01374"></a>01374     <span class="comment">/* Link nodes with alternate pronunciations at the same timepoint. */</span>
<a name="l01375"></a>01375     <span class="keywordflow">for</span> (node = dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a>; node; node = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01376"></a>01376         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *alt;
<a name="l01377"></a>01377         <span class="comment">/* Scan forward to find the next alternate, then stop. */</span>
<a name="l01378"></a>01378         <span class="keywordflow">for</span> (alt = node-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>; alt &amp;&amp; alt-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a>; alt = alt-&gt;<a class="code" href="structps__latnode__s.html#aca6f3d543a1712a1ca3bb8ec60f71c84" title="Next node in DAG (no ordering implied)">next</a>) {
<a name="l01379"></a>01379             <span class="keywordflow">if</span> (alt-&gt;<a class="code" href="structps__latnode__s.html#ae3b3dc7d14347e6380859c74b9a02589" title="Dictionary base word id.">basewid</a> == node-&gt;<a class="code" href="structps__latnode__s.html#ae3b3dc7d14347e6380859c74b9a02589" title="Dictionary base word id.">basewid</a>) {
<a name="l01380"></a>01380                 alt-&gt;<a class="code" href="structps__latnode__s.html#aa4c0a395c74acbacccde561f92fa89e4" title="Node with alternate pronunciation for this word.">alt</a> = node-&gt;<a class="code" href="structps__latnode__s.html#aa4c0a395c74acbacccde561f92fa89e4" title="Node with alternate pronunciation for this word.">alt</a>;
<a name="l01381"></a>01381                 node-&gt;<a class="code" href="structps__latnode__s.html#aa4c0a395c74acbacccde561f92fa89e4" title="Node with alternate pronunciation for this word.">alt</a> = alt;
<a name="l01382"></a>01382                 <span class="keywordflow">break</span>;
<a name="l01383"></a>01383             }
<a name="l01384"></a>01384         }
<a name="l01385"></a>01385     }
<a name="l01386"></a>01386     E_INFO(<span class="stringliteral">&quot;Lattice has %d nodes, %d links\n&quot;</span>, dag-&gt;<a class="code" href="structps__lattice__s.html#ab3690a8d16e3fa8a3b0dd3aa8277b653" title="Number of nodes in this lattice.">n_nodes</a>, nlink);
<a name="l01387"></a>01387 
<a name="l01388"></a>01388     <span class="comment">/* Minor hack: If the final node is a filler word and not &lt;/s&gt;,</span>
<a name="l01389"></a>01389 <span class="comment">     * then set its base word ID to &lt;/s&gt;, so that the language model</span>
<a name="l01390"></a>01390 <span class="comment">     * scores won&#39;t be screwed up. */</span>
<a name="l01391"></a>01391     <span class="keywordflow">if</span> (dict_filler_word(ps_search_dict(ngs), dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>))
<a name="l01392"></a>01392         dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>-&gt;<a class="code" href="structps__latnode__s.html#ae3b3dc7d14347e6380859c74b9a02589" title="Dictionary base word id.">basewid</a> = ps_search_finish_wid(ngs);
<a name="l01393"></a>01393 
<a name="l01394"></a>01394     <span class="comment">/* Free nodes unreachable from dag-&gt;end and their links */</span>
<a name="l01395"></a>01395     <a class="code" href="ps__lattice_8c.html#a6da4e36322aaab4d2ebe812bee9a4439" title="Remove nodes marked as unreachable.">ps_lattice_delete_unreachable</a>(dag);
<a name="l01396"></a>01396 
<a name="l01397"></a>01397     <span class="comment">/* Build links around silence and filler words, since they do not</span>
<a name="l01398"></a>01398 <span class="comment">     * exist in the language model. */</span>
<a name="l01399"></a>01399     <a class="code" href="ps__lattice_8c.html#a9b40adaa059978fe33959d59da1b6919" title="Bypass filler words.">ps_lattice_bypass_fillers</a>(dag, ngs-&gt;silpen, ngs-&gt;fillpen);
<a name="l01400"></a>01400 
<a name="l01401"></a>01401     search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a> = dag;
<a name="l01402"></a>01402     <span class="keywordflow">return</span> dag;
<a name="l01403"></a>01403 
<a name="l01404"></a>01404 error_out:
<a name="l01405"></a>01405     <a class="code" href="ps__lattice_8h.html#a3f90e846bde47cd1acdff165b92f5c22" title="Free a lattice.">ps_lattice_free</a>(dag);
<a name="l01406"></a>01406     <span class="keywordflow">return</span> NULL;
<a name="l01407"></a>01407 }
</pre></div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>
      <li class="navelem"><a class="el" href="ngram__search_8c.html">ngram_search.c</a>      </li>
      <li class="footer">Generated on Wed Apr 20 2011 for PocketSphinx by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </li>
    </ul>
  </div>

</body>
</html>