Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > e9280da098bff237733732ce38a34d57 > files > 42

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/fsg_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('fsg__search_8c.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<h1>src/libpocketsphinx/fsg_search.c</h1>  </div>
</div>
<div class="contents">
<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) 1999-2004 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"> *</span>
<a name="l00019"></a>00019 <span class="comment"> * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS&#39;&#39; AND </span>
<a name="l00020"></a>00020 <span class="comment"> * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, </span>
<a name="l00021"></a>00021 <span class="comment"> * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR</span>
<a name="l00022"></a>00022 <span class="comment"> * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY</span>
<a name="l00023"></a>00023 <span class="comment"> * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
<a name="l00024"></a>00024 <span class="comment"> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT </span>
<a name="l00025"></a>00025 <span class="comment"> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, </span>
<a name="l00026"></a>00026 <span class="comment"> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY </span>
<a name="l00027"></a>00027 <span class="comment"> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT </span>
<a name="l00028"></a>00028 <span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE </span>
<a name="l00029"></a>00029 <span class="comment"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<a name="l00030"></a>00030 <span class="comment"> *</span>
<a name="l00031"></a>00031 <span class="comment"> * ====================================================================</span>
<a name="l00032"></a>00032 <span class="comment"> *</span>
<a name="l00033"></a>00033 <span class="comment"> */</span>
<a name="l00034"></a>00034 
<a name="l00035"></a>00035 <span class="comment">/*</span>
<a name="l00036"></a>00036 <span class="comment"> * fsg_search.c -- Search structures for FSM decoding.</span>
<a name="l00037"></a>00037 <span class="comment"> * </span>
<a name="l00038"></a>00038 <span class="comment"> * **********************************************</span>
<a name="l00039"></a>00039 <span class="comment"> * CMU ARPA Speech Project</span>
<a name="l00040"></a>00040 <span class="comment"> *</span>
<a name="l00041"></a>00041 <span class="comment"> * Copyright (c) 2004 Carnegie Mellon University.</span>
<a name="l00042"></a>00042 <span class="comment"> * ALL RIGHTS RESERVED.</span>
<a name="l00043"></a>00043 <span class="comment"> * **********************************************</span>
<a name="l00044"></a>00044 <span class="comment"> * </span>
<a name="l00045"></a>00045 <span class="comment"> * HISTORY</span>
<a name="l00046"></a>00046 <span class="comment"> *</span>
<a name="l00047"></a>00047 <span class="comment"> * 18-Feb-2004  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon</span>
<a name="l00048"></a>00048 <span class="comment"> *              Started.</span>
<a name="l00049"></a>00049 <span class="comment"> */</span>
<a name="l00050"></a>00050 
<a name="l00051"></a>00051 <span class="comment">/* System headers. */</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00054"></a>00054 <span class="preprocessor">#include &lt;assert.h&gt;</span>
<a name="l00055"></a>00055 
<a name="l00056"></a>00056 <span class="comment">/* SphinxBase headers. */</span>
<a name="l00057"></a>00057 <span class="preprocessor">#include &lt;sphinxbase/err.h&gt;</span>
<a name="l00058"></a>00058 <span class="preprocessor">#include &lt;sphinxbase/ckd_alloc.h&gt;</span>
<a name="l00059"></a>00059 <span class="preprocessor">#include &lt;sphinxbase/strfuncs.h&gt;</span>
<a name="l00060"></a>00060 <span class="preprocessor">#include &lt;sphinxbase/cmd_ln.h&gt;</span>
<a name="l00061"></a>00061 
<a name="l00062"></a>00062 <span class="comment">/* Local headers. */</span>
<a name="l00063"></a>00063 <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="l00064"></a>00064 <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="l00065"></a>00065 <span class="preprocessor">#include &quot;fsg_search_internal.h&quot;</span>
<a name="l00066"></a>00066 <span class="preprocessor">#include &quot;fsg_history.h&quot;</span>
<a name="l00067"></a>00067 <span class="preprocessor">#include &quot;fsg_lextree.h&quot;</span>
<a name="l00068"></a>00068 
<a name="l00069"></a>00069 <span class="comment">/* Turn this on for detailed debugging dump */</span>
<a name="l00070"></a>00070 <span class="preprocessor">#define __FSG_DBG__             0</span>
<a name="l00071"></a>00071 <span class="preprocessor"></span><span class="preprocessor">#define __FSG_DBG_CHAN__        0</span>
<a name="l00072"></a>00072 <span class="preprocessor"></span>
<a name="l00073"></a>00073 <span class="keyword">static</span> <a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *fsg_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="l00074"></a>00074 <span class="keyword">static</span> <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *fsg_search_lattice(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search);
<a name="l00075"></a>00075 <span class="keyword">static</span> <span class="keywordtype">int</span> fsg_search_prob(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search);
<a name="l00076"></a>00076 
<a name="l00077"></a>00077 <span class="keyword">static</span> <a class="code" href="structps__searchfuncs__s.html" title="V-table for search algorithm.">ps_searchfuncs_t</a> fsg_funcs = {
<a name="l00078"></a>00078     <span class="comment">/* name: */</span>   <span class="stringliteral">&quot;fsg&quot;</span>,
<a name="l00079"></a>00079     <span class="comment">/* start: */</span>  fsg_search_start,
<a name="l00080"></a>00080     <span class="comment">/* step: */</span>   fsg_search_step,
<a name="l00081"></a>00081     <span class="comment">/* finish: */</span> fsg_search_finish,
<a name="l00082"></a>00082     <span class="comment">/* reinit: */</span> fsg_search_reinit,
<a name="l00083"></a>00083     <span class="comment">/* free: */</span>   fsg_search_free,
<a name="l00084"></a>00084     <span class="comment">/* lattice: */</span>  fsg_search_lattice,
<a name="l00085"></a>00085     <span class="comment">/* hyp: */</span>      fsg_search_hyp,
<a name="l00086"></a>00086     <span class="comment">/* prob: */</span>     fsg_search_prob,
<a name="l00087"></a>00087     <span class="comment">/* seg_iter: */</span> fsg_search_seg_iter,
<a name="l00088"></a>00088 };
<a name="l00089"></a>00089 
<a name="l00090"></a>00090 <a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *
<a name="l00091"></a>00091 fsg_search_init(cmd_ln_t *config,
<a name="l00092"></a>00092                 <a class="code" href="structacmod__s.html" title="Acoustic model structure.">acmod_t</a> *acmod,
<a name="l00093"></a>00093                 <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict,
<a name="l00094"></a>00094                 <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="l00095"></a>00095 {
<a name="l00096"></a>00096     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs;
<a name="l00097"></a>00097     <span class="keywordtype">char</span> <span class="keyword">const</span> *path;
<a name="l00098"></a>00098 
<a name="l00099"></a>00099     fsgs = ckd_calloc(1, <span class="keyword">sizeof</span>(*fsgs));
<a name="l00100"></a>00100     ps_search_init(ps_search_base(fsgs), &amp;fsg_funcs, config, acmod, dict, d2p);
<a name="l00101"></a>00101 
<a name="l00102"></a>00102     <span class="comment">/* Initialize HMM context. */</span>
<a name="l00103"></a>00103     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7407bdf5f311caf9d46817b3387b798c" 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="l00104"></a>00104                                     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="l00105"></a>00105     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7407bdf5f311caf9d46817b3387b798c" title="HMM context.">hmmctx</a> == NULL) {
<a name="l00106"></a>00106         ps_search_free(ps_search_base(fsgs));
<a name="l00107"></a>00107         <span class="keywordflow">return</span> NULL;
<a name="l00108"></a>00108     }
<a name="l00109"></a>00109 
<a name="l00110"></a>00110     <span class="comment">/* Intialize the search history object */</span>
<a name="l00111"></a>00111     fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a> = fsg_history_init(NULL, dict);
<a name="l00112"></a>00112     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> = -1;
<a name="l00113"></a>00113 
<a name="l00114"></a>00114     <span class="comment">/* Initialize FSG table. */</span>
<a name="l00115"></a>00115     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a> = hash_table_new(5, HASH_CASE_YES);
<a name="l00116"></a>00116 
<a name="l00117"></a>00117     <span class="comment">/* Get search pruning parameters */</span>
<a name="l00118"></a>00118     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a> = 1.0f;
<a name="l00119"></a>00119     fsgs-&gt;beam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a0cdf7dc3d3eed0d37f46cb71fdea206e" title="Global pruning threshold.">beam_orig</a>
<a name="l00120"></a>00120         = (int32) 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>))
<a name="l00121"></a>00121         &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00122"></a>00122     fsgs-&gt;pbeam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7cdf0ab2591b95d89940d51e3ab01529" title="Pruning threshold for phone transition.">pbeam_orig</a>
<a name="l00123"></a>00123         = (int32) 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>))
<a name="l00124"></a>00124         &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00125"></a>00125     fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a> = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7f3ecc2f769143e42ed958744478db3c" title="Pruning threshold for word exit.">wbeam_orig</a>
<a name="l00126"></a>00126         = (int32) 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>))
<a name="l00127"></a>00127         &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00128"></a>00128 
<a name="l00129"></a>00129     <span class="comment">/* LM related weights/penalties */</span>
<a name="l00130"></a>00130     fsgs-&gt;lw = cmd_ln_float32_r(config, <span class="stringliteral">&quot;-lw&quot;</span>);
<a name="l00131"></a>00131     fsgs-&gt;pip = (int32) (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>))
<a name="l00132"></a>00132                            * fsgs-&gt;lw)
<a name="l00133"></a>00133         &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00134"></a>00134     fsgs-&gt;<a class="code" href="structfsg__search__s.html#ae9ddc3b50d0f164926392f8ab4b019a0" title="Language weights.">wip</a> = (int32) (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>))
<a name="l00135"></a>00135                            * fsgs-&gt;lw)
<a name="l00136"></a>00136         &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l00137"></a>00137 
<a name="l00138"></a>00138     <span class="comment">/* Best path search (and confidence annotation)? */</span>
<a name="l00139"></a>00139     <span class="keywordflow">if</span> (cmd_ln_boolean_r(config, <span class="stringliteral">&quot;-bestpath&quot;</span>))
<a name="l00140"></a>00140         fsgs-&gt;<a class="code" href="structfsg__search__s.html#aba7eff57919c5a1de55eab3a62ff055a" title="Whether to run bestpath search and confidence annotation at end.">bestpath</a> = TRUE;
<a name="l00141"></a>00141 
<a name="l00142"></a>00142     <span class="comment">/* Acoustic score scale for posterior probabilities. */</span>
<a name="l00143"></a>00143     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a4d13fff2e14882b0125386fc27a4097f" 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="l00144"></a>00144 
<a name="l00145"></a>00145     E_INFO(<span class="stringliteral">&quot;FSG(beam: %d, pbeam: %d, wbeam: %d; wip: %d, pip: %d)\n&quot;</span>,
<a name="l00146"></a>00146            fsgs-&gt;<a class="code" href="structfsg__search__s.html#a0cdf7dc3d3eed0d37f46cb71fdea206e" title="Global pruning threshold.">beam_orig</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7cdf0ab2591b95d89940d51e3ab01529" title="Pruning threshold for phone transition.">pbeam_orig</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7f3ecc2f769143e42ed958744478db3c" title="Pruning threshold for word exit.">wbeam_orig</a>,
<a name="l00147"></a>00147            fsgs-&gt;<a class="code" href="structfsg__search__s.html#ae9ddc3b50d0f164926392f8ab4b019a0" title="Language weights.">wip</a>, fsgs-&gt;pip);
<a name="l00148"></a>00148 
<a name="l00149"></a>00149     <span class="comment">/* Load an FSG if one was specified in config */</span>
<a name="l00150"></a>00150     <span class="keywordflow">if</span> ((path = cmd_ln_str_r(config, <span class="stringliteral">&quot;-fsg&quot;</span>))) {
<a name="l00151"></a>00151         fsg_model_t *fsg;
<a name="l00152"></a>00152 
<a name="l00153"></a>00153         <span class="keywordflow">if</span> ((fsg = fsg_model_readfile(path, acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, fsgs-&gt;lw)) == NULL)
<a name="l00154"></a>00154             <span class="keywordflow">goto</span> error_out;
<a name="l00155"></a>00155         <span class="keywordflow">if</span> (<a class="code" href="fsg__set_8h.html#a283d0bc1d33f1f6d961bdfbb7939b853" title="Add the given FSG to the collection of FSGs known to this search object.">fsg_set_add</a>(fsgs, fsg_model_name(fsg), fsg) != fsg) {
<a name="l00156"></a>00156             fsg_model_free(fsg);
<a name="l00157"></a>00157             <span class="keywordflow">goto</span> error_out;
<a name="l00158"></a>00158         }
<a name="l00159"></a>00159         <span class="keywordflow">if</span> (<a class="code" href="fsg__set_8h.html#afbd05e7638e6a947fb056cc46dfb8fcb" title="Switch to a new FSG (identified by its string name).">fsg_set_select</a>(fsgs, fsg_model_name(fsg)) == NULL)
<a name="l00160"></a>00160             <span class="keywordflow">goto</span> error_out;
<a name="l00161"></a>00161         <span class="keywordflow">if</span> (fsg_search_reinit(ps_search_base(fsgs),
<a name="l00162"></a>00162                               ps_search_dict(fsgs),
<a name="l00163"></a>00163                               ps_search_dict2pid(fsgs)) &lt; 0)
<a name="l00164"></a>00164             <span class="keywordflow">goto</span> error_out;
<a name="l00165"></a>00165     }
<a name="l00166"></a>00166     <span class="comment">/* Or load a JSGF grammar */</span>
<a name="l00167"></a>00167     <span class="keywordflow">else</span> <span class="keywordflow">if</span> ((path = cmd_ln_str_r(config, <span class="stringliteral">&quot;-jsgf&quot;</span>))) {
<a name="l00168"></a>00168         fsg_model_t *fsg;
<a name="l00169"></a>00169         jsgf_rule_t *rule;
<a name="l00170"></a>00170         <span class="keywordtype">char</span> <span class="keyword">const</span> *toprule;
<a name="l00171"></a>00171 
<a name="l00172"></a>00172         <span class="keywordflow">if</span> ((fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a> = jsgf_parse_file(path, NULL)) == NULL)
<a name="l00173"></a>00173             <span class="keywordflow">goto</span> error_out;
<a name="l00174"></a>00174 
<a name="l00175"></a>00175         rule = NULL;
<a name="l00176"></a>00176         <span class="comment">/* Take the -toprule if specified. */</span>
<a name="l00177"></a>00177         <span class="keywordflow">if</span> ((toprule = cmd_ln_str_r(config, <span class="stringliteral">&quot;-toprule&quot;</span>))) {
<a name="l00178"></a>00178             <span class="keywordtype">char</span> *anglerule;
<a name="l00179"></a>00179             anglerule = string_join(<span class="stringliteral">&quot;&lt;&quot;</span>, toprule, <span class="stringliteral">&quot;&gt;&quot;</span>, NULL);
<a name="l00180"></a>00180             rule = jsgf_get_rule(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a>, anglerule);
<a name="l00181"></a>00181             ckd_free(anglerule);
<a name="l00182"></a>00182             <span class="keywordflow">if</span> (rule == NULL) {
<a name="l00183"></a>00183                 E_ERROR(<span class="stringliteral">&quot;Start rule %s not found\n&quot;</span>, toprule);
<a name="l00184"></a>00184                 <span class="keywordflow">goto</span> error_out;
<a name="l00185"></a>00185             }
<a name="l00186"></a>00186         }
<a name="l00187"></a>00187         <span class="comment">/* Otherwise, take the first public rule. */</span>
<a name="l00188"></a>00188         <span class="keywordflow">else</span> {
<a name="l00189"></a>00189             jsgf_rule_iter_t *itor;
<a name="l00190"></a>00190 
<a name="l00191"></a>00191             <span class="keywordflow">for</span> (itor = jsgf_rule_iter(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a>); itor;
<a name="l00192"></a>00192                  itor = jsgf_rule_iter_next(itor)) {
<a name="l00193"></a>00193                 rule = jsgf_rule_iter_rule(itor);
<a name="l00194"></a>00194                 <span class="keywordflow">if</span> (jsgf_rule_public(rule))
<a name="l00195"></a>00195                     <span class="keywordflow">break</span>;
<a name="l00196"></a>00196             }
<a name="l00197"></a>00197             <span class="keywordflow">if</span> (rule == NULL) {
<a name="l00198"></a>00198                 E_ERROR(<span class="stringliteral">&quot;No public rules found in %s\n&quot;</span>, path);
<a name="l00199"></a>00199                 <span class="keywordflow">goto</span> error_out;
<a name="l00200"></a>00200             }
<a name="l00201"></a>00201         }
<a name="l00202"></a>00202         fsg = jsgf_build_fsg(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a>, rule, acmod-&gt;<a class="code" href="structacmod__s.html#a9de7e8ac9c0c4df3d2a9ad5406787f3c" title="Log-math computation.">lmath</a>, fsgs-&gt;lw);
<a name="l00203"></a>00203         <span class="keywordflow">if</span> (<a class="code" href="fsg__set_8h.html#a283d0bc1d33f1f6d961bdfbb7939b853" title="Add the given FSG to the collection of FSGs known to this search object.">fsg_set_add</a>(fsgs, fsg_model_name(fsg), fsg) != fsg) {
<a name="l00204"></a>00204             fsg_model_free(fsg);
<a name="l00205"></a>00205             <span class="keywordflow">goto</span> error_out;
<a name="l00206"></a>00206         }
<a name="l00207"></a>00207         <span class="keywordflow">if</span> (<a class="code" href="fsg__set_8h.html#afbd05e7638e6a947fb056cc46dfb8fcb" title="Switch to a new FSG (identified by its string name).">fsg_set_select</a>(fsgs, fsg_model_name(fsg)) == NULL)
<a name="l00208"></a>00208             <span class="keywordflow">goto</span> error_out;
<a name="l00209"></a>00209         <span class="keywordflow">if</span> (fsg_search_reinit(ps_search_base(fsgs),
<a name="l00210"></a>00210                               ps_search_dict(fsgs),
<a name="l00211"></a>00211                               ps_search_dict2pid(fsgs)) &lt; 0)
<a name="l00212"></a>00212             <span class="keywordflow">goto</span> error_out;
<a name="l00213"></a>00213     }
<a name="l00214"></a>00214 
<a name="l00215"></a>00215     <span class="keywordflow">return</span> ps_search_base(fsgs);
<a name="l00216"></a>00216 
<a name="l00217"></a>00217 error_out:
<a name="l00218"></a>00218     fsg_search_free(ps_search_base(fsgs));
<a name="l00219"></a>00219     <span class="keywordflow">return</span> NULL;
<a name="l00220"></a>00220 }
<a name="l00221"></a>00221 
<a name="l00222"></a>00222 <span class="keywordtype">void</span>
<a name="l00223"></a>00223 fsg_search_free(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l00224"></a>00224 {
<a name="l00225"></a>00225     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l00226"></a>00226     hash_iter_t *itor;
<a name="l00227"></a>00227 
<a name="l00228"></a>00228     ps_search_deinit(search);
<a name="l00229"></a>00229     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a>)
<a name="l00230"></a>00230         jsgf_grammar_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5450c5baac34c706d32f26c1cf373ce3" title="Active JSGF grammar file.">jsgf</a>);
<a name="l00231"></a>00231     <a class="code" href="fsg__lextree_8c.html#a2f1ab965df1214f4d0e2008833aa20da" title="Free lextrees for an FSG.">fsg_lextree_free</a>(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>);
<a name="l00232"></a>00232     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>) {
<a name="l00233"></a>00233         fsg_history_reset(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00234"></a>00234         fsg_history_set_fsg(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, NULL, NULL);
<a name="l00235"></a>00235         fsg_history_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00236"></a>00236     }
<a name="l00237"></a>00237     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>) {
<a name="l00238"></a>00238         <span class="keywordflow">for</span> (itor = hash_table_iter(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>);
<a name="l00239"></a>00239              itor; itor = hash_table_iter_next(itor)) {
<a name="l00240"></a>00240             fsg_model_t *fsg = (fsg_model_t *) hash_entry_val(itor-&gt;ent);
<a name="l00241"></a>00241             fsg_model_free(fsg);
<a name="l00242"></a>00242         }
<a name="l00243"></a>00243         hash_table_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>);
<a name="l00244"></a>00244     }
<a name="l00245"></a>00245     hmm_context_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7407bdf5f311caf9d46817b3387b798c" title="HMM context.">hmmctx</a>);
<a name="l00246"></a>00246     ckd_free(fsgs);
<a name="l00247"></a>00247 }
<a name="l00248"></a>00248 
<a name="l00249"></a>00249 <span class="keywordtype">int</span>
<a name="l00250"></a>00250 fsg_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="l00251"></a>00251 {
<a name="l00252"></a>00252     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l00253"></a>00253 
<a name="l00254"></a>00254     <span class="comment">/* Free the old lextree */</span>
<a name="l00255"></a>00255     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>)
<a name="l00256"></a>00256         <a class="code" href="fsg__lextree_8c.html#a2f1ab965df1214f4d0e2008833aa20da" title="Free lextrees for an FSG.">fsg_lextree_free</a>(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>);
<a name="l00257"></a>00257 
<a name="l00258"></a>00258     <span class="comment">/* Free old dict2pid, dict */</span>
<a name="l00259"></a>00259     ps_search_base_reinit(search, dict, d2p);
<a name="l00260"></a>00260     
<a name="l00261"></a>00261     <span class="comment">/* Nothing to update */</span>
<a name="l00262"></a>00262     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a> == NULL)
<a name="l00263"></a>00263         <span class="keywordflow">return</span>;
<a name="l00264"></a>00264 
<a name="l00265"></a>00265     <span class="comment">/* Update the number of words (not used by this module though). */</span>
<a name="l00266"></a>00266     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="l00267"></a>00267 
<a name="l00268"></a>00268     <span class="comment">/* Allocate new lextree for the given FSG */</span>
<a name="l00269"></a>00269     fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a> = <a class="code" href="fsg__lextree_8c.html#a8c47b2983b3952886a4c889a711e1d65" title="Create, initialize, and return a new phonetic lextree for the given FSG.">fsg_lextree_init</a>(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, dict, d2p,
<a name="l00270"></a>00270                                      ps_search_acmod(fsgs)-&gt;mdef,
<a name="l00271"></a>00271                                      fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7407bdf5f311caf9d46817b3387b798c" title="HMM context.">hmmctx</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#ae9ddc3b50d0f164926392f8ab4b019a0" title="Language weights.">wip</a>, fsgs-&gt;pip);
<a name="l00272"></a>00272 
<a name="l00273"></a>00273     <span class="comment">/* Inform the history module of the new fsg */</span>
<a name="l00274"></a>00274     fsg_history_set_fsg(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, dict);
<a name="l00275"></a>00275 
<a name="l00276"></a>00276     <span class="keywordflow">return</span> 0;
<a name="l00277"></a>00277 }
<a name="l00278"></a>00278 
<a name="l00279"></a>00279 
<a name="l00280"></a>00280 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00281"></a>00281 fsg_search_add_silences(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, fsg_model_t *fsg)
<a name="l00282"></a>00282 {
<a name="l00283"></a>00283     <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict;
<a name="l00284"></a>00284     int32 wid;
<a name="l00285"></a>00285     <span class="keywordtype">int</span> n_sil;
<a name="l00286"></a>00286 
<a name="l00287"></a>00287     dict = ps_search_dict(fsgs);
<a name="l00288"></a>00288     <span class="comment">/*</span>
<a name="l00289"></a>00289 <span class="comment">     * NOTE: Unlike N-Gram search, we do not use explicit start and</span>
<a name="l00290"></a>00290 <span class="comment">     * end symbols.  This is because the start and end nodes are</span>
<a name="l00291"></a>00291 <span class="comment">     * defined in the grammar.  We do add silence/filler self-loops to</span>
<a name="l00292"></a>00292 <span class="comment">     * all states in order to allow for silence between words and at</span>
<a name="l00293"></a>00293 <span class="comment">     * the beginning and end of utterances.</span>
<a name="l00294"></a>00294 <span class="comment">     *</span>
<a name="l00295"></a>00295 <span class="comment">     * This has some implications for word graph generation, namely,</span>
<a name="l00296"></a>00296 <span class="comment">     * that there can (and usually will) be multiple start and end</span>
<a name="l00297"></a>00297 <span class="comment">     * states in the word graph.  We therefore do add explicit start</span>
<a name="l00298"></a>00298 <span class="comment">     * and end nodes to the graph.</span>
<a name="l00299"></a>00299 <span class="comment">     */</span>
<a name="l00300"></a>00300     <span class="comment">/* Add silence self-loops to all states. */</span>
<a name="l00301"></a>00301     fsg_model_add_silence(fsg, <span class="stringliteral">&quot;&lt;sil&gt;&quot;</span>, -1,
<a name="l00302"></a>00302                           cmd_ln_float32_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-silprob&quot;</span>));
<a name="l00303"></a>00303     n_sil = 0;
<a name="l00304"></a>00304     <span class="comment">/* Add self-loops for all other fillers. */</span>
<a name="l00305"></a>00305     <span class="keywordflow">for</span> (wid = dict_filler_start(dict); wid &lt; dict_filler_end(dict); ++wid) {
<a name="l00306"></a>00306         <span class="keywordtype">char</span> <span class="keyword">const</span> *word = dict_wordstr(dict, wid);
<a name="l00307"></a>00307         <span class="keywordflow">if</span> (wid == dict_startwid(dict) || wid == dict_finishwid(dict))
<a name="l00308"></a>00308             <span class="keywordflow">continue</span>;
<a name="l00309"></a>00309         fsg_model_add_silence(fsg, word, -1,
<a name="l00310"></a>00310                               cmd_ln_float32_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-fillprob&quot;</span>));
<a name="l00311"></a>00311         ++n_sil;
<a name="l00312"></a>00312     }
<a name="l00313"></a>00313 
<a name="l00314"></a>00314     <span class="keywordflow">return</span> n_sil;
<a name="l00315"></a>00315 }
<a name="l00316"></a>00316 
<a name="l00317"></a>00317 <span class="comment">/* Scans the dictionary and check if all words are present. */</span>
<a name="l00318"></a>00318 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00319"></a>00319 fsg_search_check_dict(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, fsg_model_t *fsg)
<a name="l00320"></a>00320 {
<a name="l00321"></a>00321     <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict;
<a name="l00322"></a>00322     <span class="keywordtype">int</span> i;
<a name="l00323"></a>00323 
<a name="l00324"></a>00324     dict = ps_search_dict(fsgs);
<a name="l00325"></a>00325     <span class="keywordflow">for</span> (i = 0; i &lt; fsg_model_n_word(fsg); ++i) {
<a name="l00326"></a>00326         <span class="keywordtype">char</span> <span class="keyword">const</span> *word;
<a name="l00327"></a>00327         int32 wid;
<a name="l00328"></a>00328 
<a name="l00329"></a>00329         word = fsg_model_word_str(fsg, i);
<a name="l00330"></a>00330         wid = dict_wordid(dict, word);
<a name="l00331"></a>00331         <span class="keywordflow">if</span> (wid == <a class="code" href="s3types_8h.html#a5c42410b7125da611210c5a4be29898b" title="Dictionary word id.">BAD_S3WID</a>) {
<a name="l00332"></a>00332             E_ERROR(<span class="stringliteral">&quot;The word &#39;%s&#39; is missing in the dictionary\n&quot;</span>, word);
<a name="l00333"></a>00333             <span class="keywordflow">return</span> FALSE;
<a name="l00334"></a>00334         }
<a name="l00335"></a>00335     }
<a name="l00336"></a>00336 
<a name="l00337"></a>00337     <span class="keywordflow">return</span> TRUE;
<a name="l00338"></a>00338 }
<a name="l00339"></a>00339 
<a name="l00340"></a>00340 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00341"></a>00341 fsg_search_add_altpron(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, fsg_model_t *fsg)
<a name="l00342"></a>00342 {
<a name="l00343"></a>00343     <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict;
<a name="l00344"></a>00344     <span class="keywordtype">int</span> n_alt, n_word;
<a name="l00345"></a>00345     <span class="keywordtype">int</span> i;
<a name="l00346"></a>00346 
<a name="l00347"></a>00347     dict = ps_search_dict(fsgs);
<a name="l00348"></a>00348     <span class="comment">/* Scan FSG&#39;s vocabulary for words that have alternate pronunciations. */</span>
<a name="l00349"></a>00349     n_alt = 0;
<a name="l00350"></a>00350     n_word = fsg_model_n_word(fsg);
<a name="l00351"></a>00351     <span class="keywordflow">for</span> (i = 0; i &lt; n_word; ++i) {
<a name="l00352"></a>00352         <span class="keywordtype">char</span> <span class="keyword">const</span> *word;
<a name="l00353"></a>00353         int32 wid;
<a name="l00354"></a>00354 
<a name="l00355"></a>00355         word = fsg_model_word_str(fsg, i);
<a name="l00356"></a>00356         wid = dict_wordid(dict, word);
<a name="l00357"></a>00357         <span class="keywordflow">if</span> (wid != <a class="code" href="s3types_8h.html#a5c42410b7125da611210c5a4be29898b" title="Dictionary word id.">BAD_S3WID</a>) {
<a name="l00358"></a>00358             <span class="keywordflow">while</span> ((wid = dict_nextalt(dict, wid)) != <a class="code" href="s3types_8h.html#a5c42410b7125da611210c5a4be29898b" title="Dictionary word id.">BAD_S3WID</a>) {
<a name="l00359"></a>00359                 n_alt += fsg_model_add_alt(fsg, word, dict_wordstr(dict, wid));
<a name="l00360"></a>00360             }
<a name="l00361"></a>00361         }
<a name="l00362"></a>00362     }
<a name="l00363"></a>00363 
<a name="l00364"></a>00364     E_INFO(<span class="stringliteral">&quot;Added %d alternate word transitions\n&quot;</span>, n_alt);
<a name="l00365"></a>00365     <span class="keywordflow">return</span> n_alt;
<a name="l00366"></a>00366 }
<a name="l00367"></a>00367 
<a name="l00368"></a>00368 fsg_model_t *
<a name="l00369"></a><a class="code" href="fsg__set_8h.html#a91e2b8cba4e0ba30478260c18a36ed26">00369</a> <a class="code" href="fsg__set_8h.html#a91e2b8cba4e0ba30478260c18a36ed26" title="Lookup the FSG associated with the given name.">fsg_set_get_fsg</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
<a name="l00370"></a>00370 {
<a name="l00371"></a>00371     <span class="keywordtype">void</span> *val;
<a name="l00372"></a>00372 
<a name="l00373"></a>00373     <span class="keywordflow">if</span> (hash_table_lookup(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>, name, &amp;val) &lt; 0)
<a name="l00374"></a>00374         <span class="keywordflow">return</span> NULL;
<a name="l00375"></a>00375     <span class="keywordflow">return</span> (fsg_model_t *)val;
<a name="l00376"></a>00376 }
<a name="l00377"></a>00377 
<a name="l00378"></a>00378 fsg_model_t *
<a name="l00379"></a><a class="code" href="fsg__set_8h.html#a283d0bc1d33f1f6d961bdfbb7939b853">00379</a> <a class="code" href="fsg__set_8h.html#a283d0bc1d33f1f6d961bdfbb7939b853" title="Add the given FSG to the collection of FSGs known to this search object.">fsg_set_add</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <span class="keywordtype">char</span> <span class="keyword">const</span> *name, fsg_model_t *fsg)
<a name="l00380"></a>00380 {
<a name="l00381"></a>00381     <span class="keywordflow">if</span> (name == NULL)
<a name="l00382"></a>00382         name = fsg_model_name(fsg);
<a name="l00383"></a>00383 
<a name="l00384"></a>00384     <span class="keywordflow">if</span> (!fsg_search_check_dict(fsgs, fsg))
<a name="l00385"></a>00385         <span class="keywordflow">return</span> NULL;
<a name="l00386"></a>00386 
<a name="l00387"></a>00387     <span class="comment">/* Add silence transitions and alternate words. */</span>
<a name="l00388"></a>00388     <span class="keywordflow">if</span> (cmd_ln_boolean_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-fsgusefiller&quot;</span>)
<a name="l00389"></a>00389         &amp;&amp; !fsg_model_has_sil(fsg))
<a name="l00390"></a>00390         fsg_search_add_silences(fsgs, fsg);
<a name="l00391"></a>00391     <span class="keywordflow">if</span> (cmd_ln_boolean_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-fsgusealtpron&quot;</span>)
<a name="l00392"></a>00392         &amp;&amp; !fsg_model_has_alt(fsg))
<a name="l00393"></a>00393         fsg_search_add_altpron(fsgs, fsg);
<a name="l00394"></a>00394 
<a name="l00395"></a>00395     <span class="keywordflow">return</span> (fsg_model_t *)hash_table_enter(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>, name, fsg);
<a name="l00396"></a>00396 }
<a name="l00397"></a>00397 
<a name="l00398"></a>00398 
<a name="l00399"></a>00399 fsg_model_t *
<a name="l00400"></a><a class="code" href="fsg__set_8h.html#a48e53ea0b48930ab48a445240162746d">00400</a> <a class="code" href="fsg__set_8h.html#a48e53ea0b48930ab48a445240162746d" title="Like fsg_set_del_fsg(), but identifies the FSG by its name.">fsg_set_remove_byname</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <span class="keywordtype">char</span> <span class="keyword">const</span> *key)
<a name="l00401"></a>00401 {
<a name="l00402"></a>00402     fsg_model_t *oldfsg;
<a name="l00403"></a>00403     <span class="keywordtype">void</span> *val;
<a name="l00404"></a>00404 
<a name="l00405"></a>00405     <span class="comment">/* Look for the matching FSG. */</span>
<a name="l00406"></a>00406     <span class="keywordflow">if</span> (hash_table_lookup(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>, key, &amp;val) &lt; 0) {
<a name="l00407"></a>00407         E_ERROR(<span class="stringliteral">&quot;FSG `%s&#39; to be deleted not found\n&quot;</span>, key);
<a name="l00408"></a>00408         <span class="keywordflow">return</span> NULL;
<a name="l00409"></a>00409     }
<a name="l00410"></a>00410     oldfsg = val;
<a name="l00411"></a>00411 
<a name="l00412"></a>00412     <span class="comment">/* Remove it from the FSG table. */</span>
<a name="l00413"></a>00413     hash_table_delete(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>, key);
<a name="l00414"></a>00414     <span class="comment">/* If this was the currently active FSG, also delete other stuff */</span>
<a name="l00415"></a>00415     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a> == oldfsg) {
<a name="l00416"></a>00416         <a class="code" href="fsg__lextree_8c.html#a2f1ab965df1214f4d0e2008833aa20da" title="Free lextrees for an FSG.">fsg_lextree_free</a>(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>);
<a name="l00417"></a>00417         fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a> = NULL;
<a name="l00418"></a>00418         fsg_history_set_fsg(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, NULL, NULL);
<a name="l00419"></a>00419         fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a> = NULL;
<a name="l00420"></a>00420     }
<a name="l00421"></a>00421     <span class="keywordflow">return</span> oldfsg;
<a name="l00422"></a>00422 }
<a name="l00423"></a>00423 
<a name="l00424"></a>00424 
<a name="l00425"></a>00425 fsg_model_t *
<a name="l00426"></a><a class="code" href="fsg__set_8h.html#ac46a51a7d298277e978821bb61236062">00426</a> <a class="code" href="fsg__set_8h.html#ac46a51a7d298277e978821bb61236062" title="Delete the given FSG from the known collection.">fsg_set_remove</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, fsg_model_t *fsg)
<a name="l00427"></a>00427 {
<a name="l00428"></a>00428     <span class="keywordtype">char</span> <span class="keyword">const</span> *key;
<a name="l00429"></a>00429     hash_iter_t *itor;
<a name="l00430"></a>00430 
<a name="l00431"></a>00431     key = NULL;
<a name="l00432"></a>00432     <span class="keywordflow">for</span> (itor = hash_table_iter(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>);
<a name="l00433"></a>00433          itor; itor = hash_table_iter_next(itor)) {
<a name="l00434"></a>00434         fsg_model_t *oldfsg;
<a name="l00435"></a>00435 
<a name="l00436"></a>00436         oldfsg = (fsg_model_t *) hash_entry_val(itor-&gt;ent);
<a name="l00437"></a>00437         <span class="keywordflow">if</span> (oldfsg == fsg) {
<a name="l00438"></a>00438             key = hash_entry_key(itor-&gt;ent);
<a name="l00439"></a>00439             hash_table_iter_free(itor);
<a name="l00440"></a>00440             <span class="keywordflow">break</span>;
<a name="l00441"></a>00441         }
<a name="l00442"></a>00442     }
<a name="l00443"></a>00443     <span class="keywordflow">if</span> (key == NULL) {
<a name="l00444"></a>00444         E_WARN(<span class="stringliteral">&quot;FSG &#39;%s&#39; to be deleted not found\n&quot;</span>, fsg_model_name(fsg));
<a name="l00445"></a>00445         <span class="keywordflow">return</span> NULL;
<a name="l00446"></a>00446     }
<a name="l00447"></a>00447     <span class="keywordflow">else</span>
<a name="l00448"></a>00448         <span class="keywordflow">return</span> <a class="code" href="fsg__set_8h.html#a48e53ea0b48930ab48a445240162746d" title="Like fsg_set_del_fsg(), but identifies the FSG by its name.">fsg_set_remove_byname</a>(fsgs, key);
<a name="l00449"></a>00449 }
<a name="l00450"></a>00450 
<a name="l00451"></a>00451 
<a name="l00452"></a>00452 fsg_model_t *
<a name="l00453"></a><a class="code" href="fsg__set_8h.html#afbd05e7638e6a947fb056cc46dfb8fcb">00453</a> <a class="code" href="fsg__set_8h.html#afbd05e7638e6a947fb056cc46dfb8fcb" title="Switch to a new FSG (identified by its string name).">fsg_set_select</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
<a name="l00454"></a>00454 {
<a name="l00455"></a>00455     fsg_model_t *fsg;
<a name="l00456"></a>00456 
<a name="l00457"></a>00457     fsg = <a class="code" href="fsg__set_8h.html#a91e2b8cba4e0ba30478260c18a36ed26" title="Lookup the FSG associated with the given name.">fsg_set_get_fsg</a>(fsgs, name);
<a name="l00458"></a>00458     <span class="keywordflow">if</span> (fsg == NULL) {
<a name="l00459"></a>00459         E_ERROR(<span class="stringliteral">&quot;FSG &#39;%s&#39; not known; cannot make it current\n&quot;</span>, name);
<a name="l00460"></a>00460         <span class="keywordflow">return</span> NULL;
<a name="l00461"></a>00461     }
<a name="l00462"></a>00462     fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a> = fsg;
<a name="l00463"></a>00463     <span class="keywordflow">return</span> fsg;
<a name="l00464"></a>00464 }
<a name="l00465"></a>00465 
<a name="l00466"></a>00466 <a class="code" href="fsg__set_8h.html#abb8eed644c915f0599dc2cce38767b70" title="Iterator over finite-state grammars.">fsg_set_iter_t</a> *
<a name="l00467"></a><a class="code" href="fsg__set_8h.html#ae258fe4457affc6de5548330f33470ca">00467</a> <a class="code" href="fsg__set_8h.html#ae258fe4457affc6de5548330f33470ca" title="Get an iterator over all finite-state grammars in a set.">fsg_set_iter</a>(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_set_t</a> *fsgs)
<a name="l00468"></a>00468 {
<a name="l00469"></a>00469     <span class="keywordflow">return</span> hash_table_iter(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a3d31a88c719aaf36ecae5c96ecddbd73" title="Table of all FSGs loaded.">fsgs</a>);
<a name="l00470"></a>00470 }
<a name="l00471"></a>00471 
<a name="l00472"></a>00472 <a class="code" href="fsg__set_8h.html#abb8eed644c915f0599dc2cce38767b70" title="Iterator over finite-state grammars.">fsg_set_iter_t</a> *
<a name="l00473"></a><a class="code" href="fsg__set_8h.html#a50a455ce026c87a66d85363e874e982d">00473</a> <a class="code" href="fsg__set_8h.html#a50a455ce026c87a66d85363e874e982d" title="Advance an iterator to the next grammar in the set.">fsg_set_iter_next</a>(<a class="code" href="fsg__set_8h.html#abb8eed644c915f0599dc2cce38767b70" title="Iterator over finite-state grammars.">fsg_set_iter_t</a> *itor)
<a name="l00474"></a>00474 {
<a name="l00475"></a>00475     <span class="keywordflow">return</span> hash_table_iter_next(itor);
<a name="l00476"></a>00476 }
<a name="l00477"></a>00477 
<a name="l00478"></a>00478 fsg_model_t *
<a name="l00479"></a><a class="code" href="fsg__set_8h.html#a139c12323411b8366c66e97e112ca8c1">00479</a> <a class="code" href="fsg__set_8h.html#a139c12323411b8366c66e97e112ca8c1" title="Get the current rule in an FSG iterator.">fsg_set_iter_fsg</a>(<a class="code" href="fsg__set_8h.html#abb8eed644c915f0599dc2cce38767b70" title="Iterator over finite-state grammars.">fsg_set_iter_t</a> *itor)
<a name="l00480"></a>00480 {
<a name="l00481"></a>00481     <span class="keywordflow">return</span> ((fsg_model_t *)itor-&gt;ent-&gt;val);
<a name="l00482"></a>00482 }
<a name="l00483"></a>00483 
<a name="l00484"></a>00484 <span class="keywordtype">void</span>
<a name="l00485"></a><a class="code" href="fsg__set_8h.html#a4e31d748ffd9d99fc626c2a1036c3699">00485</a> <a class="code" href="fsg__set_8h.html#a4e31d748ffd9d99fc626c2a1036c3699" title="Free an FSG iterator (if the end hasn&amp;#39;t been reached).">fsg_set_iter_free</a>(<a class="code" href="fsg__set_8h.html#abb8eed644c915f0599dc2cce38767b70" title="Iterator over finite-state grammars.">fsg_set_iter_t</a> *itor)
<a name="l00486"></a>00486 {
<a name="l00487"></a>00487     hash_table_iter_free(itor);
<a name="l00488"></a>00488 }
<a name="l00489"></a>00489 
<a name="l00490"></a>00490 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00491"></a>00491 fsg_search_sen_active(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs)
<a name="l00492"></a>00492 {
<a name="l00493"></a>00493     gnode_t *gn;
<a name="l00494"></a>00494     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *pnode;
<a name="l00495"></a>00495     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00496"></a>00496 
<a name="l00497"></a>00497     <a class="code" href="acmod_8c.html#aed43f033f434e34fd90c975909d81cb2" title="Clear set of active senones.">acmod_clear_active</a>(ps_search_acmod(fsgs));
<a name="l00498"></a>00498 
<a name="l00499"></a>00499     <span class="keywordflow">for</span> (gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>; gn; gn = gnode_next(gn)) {
<a name="l00500"></a>00500         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l00501"></a>00501         hmm = fsg_pnode_hmmptr(pnode);
<a name="l00502"></a>00502         assert(hmm_frame(hmm) == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l00503"></a>00503         <a class="code" href="acmod_8c.html#a2a7f67d462279b2bc4774c7967ae61c7" title="Activate senones associated with an HMM.">acmod_activate_hmm</a>(ps_search_acmod(fsgs), hmm);
<a name="l00504"></a>00504     }
<a name="l00505"></a>00505 }
<a name="l00506"></a>00506 
<a name="l00507"></a>00507 
<a name="l00508"></a>00508 <span class="comment">/*</span>
<a name="l00509"></a>00509 <span class="comment"> * Evaluate all the active HMMs.</span>
<a name="l00510"></a>00510 <span class="comment"> * (Executed once per frame.)</span>
<a name="l00511"></a>00511 <span class="comment"> */</span>
<a name="l00512"></a>00512 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00513"></a>00513 fsg_search_hmm_eval(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs)
<a name="l00514"></a>00514 {
<a name="l00515"></a>00515     gnode_t *gn;
<a name="l00516"></a>00516     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *pnode;
<a name="l00517"></a>00517     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00518"></a>00518     int32 bestscore;
<a name="l00519"></a>00519     int32 n, maxhmmpf;
<a name="l00520"></a>00520 
<a name="l00521"></a>00521     bestscore = <a class="code" href="hmm_8h.html#a833f100ee293ad0f1c03f2a5ef9be77a" title="Large &amp;quot;bad&amp;quot; score.">WORST_SCORE</a>;
<a name="l00522"></a>00522 
<a name="l00523"></a>00523     <span class="keywordflow">if</span> (!fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>) {
<a name="l00524"></a>00524         E_ERROR(<span class="stringliteral">&quot;Frame %d: No active HMM!!\n&quot;</span>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l00525"></a>00525         <span class="keywordflow">return</span>;
<a name="l00526"></a>00526     }
<a name="l00527"></a>00527 
<a name="l00528"></a>00528     <span class="keywordflow">for</span> (n = 0, gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>; gn; gn = gnode_next(gn), n++) {
<a name="l00529"></a>00529         int32 score;
<a name="l00530"></a>00530 
<a name="l00531"></a>00531         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l00532"></a>00532         hmm = fsg_pnode_hmmptr(pnode);
<a name="l00533"></a>00533         assert(hmm_frame(hmm) == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l00534"></a>00534 
<a name="l00535"></a>00535 <span class="preprocessor">#if __FSG_DBG__</span>
<a name="l00536"></a>00536 <span class="preprocessor"></span>        E_INFO(<span class="stringliteral">&quot;pnode(%08x) active @frm %5d\n&quot;</span>, (int32) pnode,
<a name="l00537"></a>00537                fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l00538"></a>00538         hmm_dump(hmm, stdout);
<a name="l00539"></a>00539 <span class="preprocessor">#endif</span>
<a name="l00540"></a>00540 <span class="preprocessor"></span>        score = hmm_vit_eval(hmm);
<a name="l00541"></a>00541 <span class="preprocessor">#if __FSG_DBG_CHAN__</span>
<a name="l00542"></a>00542 <span class="preprocessor"></span>        E_INFO(<span class="stringliteral">&quot;pnode(%08x) after eval @frm %5d\n&quot;</span>,
<a name="l00543"></a>00543                (int32) pnode, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l00544"></a>00544         hmm_dump(hmm, stdout);
<a name="l00545"></a>00545 <span class="preprocessor">#endif</span>
<a name="l00546"></a>00546 <span class="preprocessor"></span>
<a name="l00547"></a>00547         <span class="keywordflow">if</span> (score <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> bestscore)
<a name="l00548"></a>00548             bestscore = score;
<a name="l00549"></a>00549     }
<a name="l00550"></a>00550 
<a name="l00551"></a>00551 <span class="preprocessor">#if __FSG_DBG__</span>
<a name="l00552"></a>00552 <span class="preprocessor"></span>    E_INFO(<span class="stringliteral">&quot;[%5d] %6d HMM; bestscr: %11d\n&quot;</span>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, n, bestscore);
<a name="l00553"></a>00553 <span class="preprocessor">#endif</span>
<a name="l00554"></a>00554 <span class="preprocessor"></span>    fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7e3d7375b4a33af339e8b55885677faa" title="Total HMMs evaluated this utt.">n_hmm_eval</a> += n;
<a name="l00555"></a>00555 
<a name="l00556"></a>00556     <span class="comment">/* Adjust beams if #active HMMs larger than absolute threshold */</span>
<a name="l00557"></a>00557     maxhmmpf = cmd_ln_int32_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-maxhmmpf&quot;</span>);
<a name="l00558"></a>00558     <span class="keywordflow">if</span> (maxhmmpf != -1 &amp;&amp; n &gt; maxhmmpf) {
<a name="l00559"></a>00559         <span class="comment">/*</span>
<a name="l00560"></a>00560 <span class="comment">         * Too many HMMs active; reduce the beam factor applied to the default</span>
<a name="l00561"></a>00561 <span class="comment">         * beams, but not if the factor is already at a floor (0.1).</span>
<a name="l00562"></a>00562 <span class="comment">         */</span>
<a name="l00563"></a>00563         <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a> &gt; 0.1) {        <span class="comment">/* Hack!!  Hardwired constant 0.1 */</span>
<a name="l00564"></a>00564             fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a> *= 0.9f;        <span class="comment">/* Hack!!  Hardwired constant 0.9 */</span>
<a name="l00565"></a>00565             fsgs-&gt;beam =
<a name="l00566"></a>00566                 (int32) (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a0cdf7dc3d3eed0d37f46cb71fdea206e" title="Global pruning threshold.">beam_orig</a> * fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a>);
<a name="l00567"></a>00567             fsgs-&gt;pbeam =
<a name="l00568"></a>00568                 (int32) (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7cdf0ab2591b95d89940d51e3ab01529" title="Pruning threshold for phone transition.">pbeam_orig</a> * fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a>);
<a name="l00569"></a>00569             fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a> =
<a name="l00570"></a>00570                 (int32) (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7f3ecc2f769143e42ed958744478db3c" title="Pruning threshold for word exit.">wbeam_orig</a> * fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a>);
<a name="l00571"></a>00571         }
<a name="l00572"></a>00572     }
<a name="l00573"></a>00573     <span class="keywordflow">else</span> {
<a name="l00574"></a>00574         fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a> = 1.0f;
<a name="l00575"></a>00575         fsgs-&gt;beam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a0cdf7dc3d3eed0d37f46cb71fdea206e" title="Global pruning threshold.">beam_orig</a>;
<a name="l00576"></a>00576         fsgs-&gt;pbeam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7cdf0ab2591b95d89940d51e3ab01529" title="Pruning threshold for phone transition.">pbeam_orig</a>;
<a name="l00577"></a>00577         fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a> = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7f3ecc2f769143e42ed958744478db3c" title="Pruning threshold for word exit.">wbeam_orig</a>;
<a name="l00578"></a>00578     }
<a name="l00579"></a>00579 
<a name="l00580"></a>00580     <span class="keywordflow">if</span> (n &gt; fsg_lextree_n_pnode(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>))
<a name="l00581"></a>00581         E_FATAL(<span class="stringliteral">&quot;PANIC! Frame %d: #HMM evaluated(%d) &gt; #PNodes(%d)\n&quot;</span>,
<a name="l00582"></a>00582                 fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, n, fsg_lextree_n_pnode(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>));
<a name="l00583"></a>00583 
<a name="l00584"></a>00584     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> = bestscore;
<a name="l00585"></a>00585 }
<a name="l00586"></a>00586 
<a name="l00587"></a>00587 
<a name="l00588"></a>00588 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00589"></a>00589 fsg_search_pnode_trans(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> * pnode)
<a name="l00590"></a>00590 {
<a name="l00591"></a>00591     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *child;
<a name="l00592"></a>00592     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00593"></a>00593     int32 newscore, thresh, nf;
<a name="l00594"></a>00594 
<a name="l00595"></a>00595     assert(pnode);
<a name="l00596"></a>00596     assert(!fsg_pnode_leaf(pnode));
<a name="l00597"></a>00597 
<a name="l00598"></a>00598     nf = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> + 1;
<a name="l00599"></a>00599     thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;beam;
<a name="l00600"></a>00600 
<a name="l00601"></a>00601     hmm = fsg_pnode_hmmptr(pnode);
<a name="l00602"></a>00602 
<a name="l00603"></a>00603     <span class="keywordflow">for</span> (child = fsg_pnode_succ(pnode);
<a name="l00604"></a>00604          child; child = fsg_pnode_sibling(child)) {
<a name="l00605"></a>00605         newscore = hmm_out_score(hmm) + child-&gt;logs2prob;
<a name="l00606"></a>00606 
<a name="l00607"></a>00607         <span class="keywordflow">if</span> ((newscore <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> thresh)
<a name="l00608"></a>00608             &amp;&amp; (newscore <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> hmm_in_score(&amp;child-&gt;hmm))) {
<a name="l00609"></a>00609             <span class="comment">/* Incoming score &gt; pruning threshold and &gt; target&#39;s existing score */</span>
<a name="l00610"></a>00610             <span class="keywordflow">if</span> (hmm_frame(&amp;child-&gt;hmm) &lt; nf) {
<a name="l00611"></a>00611                 <span class="comment">/* Child node not yet activated; do so */</span>
<a name="l00612"></a>00612                 fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> =
<a name="l00613"></a>00613                     glist_add_ptr(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>,
<a name="l00614"></a>00614                                   (<span class="keywordtype">void</span> *) child);
<a name="l00615"></a>00615             }
<a name="l00616"></a>00616 
<a name="l00617"></a>00617             hmm_enter(&amp;child-&gt;hmm, newscore, hmm_out_history(hmm), nf);
<a name="l00618"></a>00618         }
<a name="l00619"></a>00619     }
<a name="l00620"></a>00620 }
<a name="l00621"></a>00621 
<a name="l00622"></a>00622 
<a name="l00623"></a>00623 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00624"></a>00624 fsg_search_pnode_exit(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> * pnode)
<a name="l00625"></a>00625 {
<a name="l00626"></a>00626     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00627"></a>00627     fsg_link_t *fl;
<a name="l00628"></a>00628     int32 wid;
<a name="l00629"></a>00629     <a class="code" href="structfsg__pnode__ctxt__t.html">fsg_pnode_ctxt_t</a> ctxt;
<a name="l00630"></a>00630 
<a name="l00631"></a>00631     assert(pnode);
<a name="l00632"></a>00632     assert(fsg_pnode_leaf(pnode));
<a name="l00633"></a>00633 
<a name="l00634"></a>00634     hmm = fsg_pnode_hmmptr(pnode);
<a name="l00635"></a>00635     fl = fsg_pnode_fsglink(pnode);
<a name="l00636"></a>00636     assert(fl);
<a name="l00637"></a>00637 
<a name="l00638"></a>00638     wid = fsg_link_wid(fl);
<a name="l00639"></a>00639     assert(wid &gt;= 0);
<a name="l00640"></a>00640 
<a name="l00641"></a>00641 <span class="preprocessor">#if __FSG_DBG__</span>
<a name="l00642"></a>00642 <span class="preprocessor"></span>    E_INFO(<span class="stringliteral">&quot;[%5d] Exit(%08x) %10d(score) %5d(pred)\n&quot;</span>,
<a name="l00643"></a>00643            fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, (int32) pnode,
<a name="l00644"></a>00644            hmm_out_score(hmm), hmm_out_history(hmm));
<a name="l00645"></a>00645 <span class="preprocessor">#endif</span>
<a name="l00646"></a>00646 <span class="preprocessor"></span>
<a name="l00647"></a>00647     <span class="comment">/*</span>
<a name="l00648"></a>00648 <span class="comment">     * Check if this is filler or single phone word; these do not model right</span>
<a name="l00649"></a>00649 <span class="comment">     * context (i.e., the exit score applies to all right contexts).</span>
<a name="l00650"></a>00650 <span class="comment">     */</span>
<a name="l00651"></a>00651     <span class="keywordflow">if</span> (fsg_model_is_filler(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid)
<a name="l00652"></a>00652         <span class="comment">/* FIXME: This might be slow due to repeated calls to dict_to_id(). */</span>
<a name="l00653"></a>00653         || (dict_is_single_phone(ps_search_dict(fsgs),
<a name="l00654"></a>00654                                    dict_wordid(ps_search_dict(fsgs),
<a name="l00655"></a>00655                                                fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid))))) {
<a name="l00656"></a>00656         <span class="comment">/* Create a dummy context structure that applies to all right contexts */</span>
<a name="l00657"></a>00657         <a class="code" href="fsg__lextree_8c.html#a98fd94d024df264025e30c909c82cb56" title="Set all flags on in the given context bitvector.">fsg_pnode_add_all_ctxt</a>(&amp;ctxt);
<a name="l00658"></a>00658 
<a name="l00659"></a>00659         <span class="comment">/* Create history table entry for this word exit */</span>
<a name="l00660"></a>00660         fsg_history_entry_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>,
<a name="l00661"></a>00661                               fl,
<a name="l00662"></a>00662                               fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>,
<a name="l00663"></a>00663                               hmm_out_score(hmm),
<a name="l00664"></a>00664                               hmm_out_history(hmm),
<a name="l00665"></a>00665                               pnode-&gt;ci_ext, ctxt);
<a name="l00666"></a>00666 
<a name="l00667"></a>00667     }
<a name="l00668"></a>00668     <span class="keywordflow">else</span> {
<a name="l00669"></a>00669         <span class="comment">/* Create history table entry for this word exit */</span>
<a name="l00670"></a>00670         fsg_history_entry_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>,
<a name="l00671"></a>00671                               fl,
<a name="l00672"></a>00672                               fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>,
<a name="l00673"></a>00673                               hmm_out_score(hmm),
<a name="l00674"></a>00674                               hmm_out_history(hmm),
<a name="l00675"></a>00675                               pnode-&gt;ci_ext, pnode-&gt;ctxt);
<a name="l00676"></a>00676     }
<a name="l00677"></a>00677 }
<a name="l00678"></a>00678 
<a name="l00679"></a>00679 
<a name="l00680"></a>00680 <span class="comment">/*</span>
<a name="l00681"></a>00681 <span class="comment"> * (Beam) prune the just evaluated HMMs, determine which ones remain</span>
<a name="l00682"></a>00682 <span class="comment"> * active, which ones transition to successors, which ones exit and</span>
<a name="l00683"></a>00683 <span class="comment"> * terminate in their respective destination FSM states.</span>
<a name="l00684"></a>00684 <span class="comment"> * (Executed once per frame.)</span>
<a name="l00685"></a>00685 <span class="comment"> */</span>
<a name="l00686"></a>00686 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00687"></a>00687 fsg_search_hmm_prune_prop(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs)
<a name="l00688"></a>00688 {
<a name="l00689"></a>00689     gnode_t *gn;
<a name="l00690"></a>00690     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *pnode;
<a name="l00691"></a>00691     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00692"></a>00692     int32 thresh, word_thresh, phone_thresh;
<a name="l00693"></a>00693 
<a name="l00694"></a>00694     assert(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> == NULL);
<a name="l00695"></a>00695 
<a name="l00696"></a>00696     thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;beam;
<a name="l00697"></a>00697     phone_thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;pbeam;
<a name="l00698"></a>00698     word_thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a>;
<a name="l00699"></a>00699 
<a name="l00700"></a>00700     <span class="keywordflow">for</span> (gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>; gn; gn = gnode_next(gn)) {
<a name="l00701"></a>00701         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l00702"></a>00702         hmm = fsg_pnode_hmmptr(pnode);
<a name="l00703"></a>00703 
<a name="l00704"></a>00704         <span class="keywordflow">if</span> (hmm_bestscore(hmm) &gt;= thresh) {
<a name="l00705"></a>00705             <span class="comment">/* Keep this HMM active in the next frame */</span>
<a name="l00706"></a>00706             <span class="keywordflow">if</span> (hmm_frame(hmm) == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>) {
<a name="l00707"></a>00707                 hmm_frame(hmm) = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> + 1;
<a name="l00708"></a>00708                 fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> =
<a name="l00709"></a>00709                     glist_add_ptr(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>,
<a name="l00710"></a>00710                                   (<span class="keywordtype">void</span> *) pnode);
<a name="l00711"></a>00711             }
<a name="l00712"></a>00712             <span class="keywordflow">else</span> {
<a name="l00713"></a>00713                 assert(hmm_frame(hmm) == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> + 1);
<a name="l00714"></a>00714             }
<a name="l00715"></a>00715 
<a name="l00716"></a>00716             <span class="keywordflow">if</span> (!fsg_pnode_leaf(pnode)) {
<a name="l00717"></a>00717                 <span class="keywordflow">if</span> (hmm_out_score(hmm) &gt;= phone_thresh) {
<a name="l00718"></a>00718                     <span class="comment">/* Transition out of this phone into its children */</span>
<a name="l00719"></a>00719                     fsg_search_pnode_trans(fsgs, pnode);
<a name="l00720"></a>00720                 }
<a name="l00721"></a>00721             }
<a name="l00722"></a>00722             <span class="keywordflow">else</span> {
<a name="l00723"></a>00723                 <span class="keywordflow">if</span> (hmm_out_score(hmm) &gt;= word_thresh) {
<a name="l00724"></a>00724                     <span class="comment">/* Transition out of leaf node into destination FSG state */</span>
<a name="l00725"></a>00725                     fsg_search_pnode_exit(fsgs, pnode);
<a name="l00726"></a>00726                 }
<a name="l00727"></a>00727             }
<a name="l00728"></a>00728         }
<a name="l00729"></a>00729     }
<a name="l00730"></a>00730 }
<a name="l00731"></a>00731 
<a name="l00732"></a>00732 
<a name="l00733"></a>00733 <span class="comment">/*</span>
<a name="l00734"></a>00734 <span class="comment"> * Propagate newly created history entries through null transitions.</span>
<a name="l00735"></a>00735 <span class="comment"> */</span>
<a name="l00736"></a>00736 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00737"></a>00737 fsg_search_null_prop(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs)
<a name="l00738"></a>00738 {
<a name="l00739"></a>00739     int32 bpidx, n_entries, thresh, newscore;
<a name="l00740"></a>00740     <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry;
<a name="l00741"></a>00741     fsg_link_t *l;
<a name="l00742"></a>00742     int32 s;
<a name="l00743"></a>00743     fsg_model_t *fsg;
<a name="l00744"></a>00744 
<a name="l00745"></a>00745     fsg = fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>;
<a name="l00746"></a>00746     thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a>; <span class="comment">/* Which beam really?? */</span>
<a name="l00747"></a>00747 
<a name="l00748"></a>00748     n_entries = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00749"></a>00749 
<a name="l00750"></a>00750     <span class="keywordflow">for</span> (bpidx = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a24d59609008ac132dca256d36a89f9c8" title="First history entry index this frame.">bpidx_start</a>; bpidx &lt; n_entries; bpidx++) {
<a name="l00751"></a>00751         fsg_arciter_t *itor;
<a name="l00752"></a>00752         hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bpidx);
<a name="l00753"></a>00753 
<a name="l00754"></a>00754         l = fsg_hist_entry_fsglink(hist_entry);
<a name="l00755"></a>00755 
<a name="l00756"></a>00756         <span class="comment">/* Destination FSG state for history entry */</span>
<a name="l00757"></a>00757         s = l ? fsg_link_to_state(l) : fsg_model_start_state(fsg);
<a name="l00758"></a>00758 
<a name="l00759"></a>00759         <span class="comment">/*</span>
<a name="l00760"></a>00760 <span class="comment">         * Check null transitions from d to all other states.  (Only need to</span>
<a name="l00761"></a>00761 <span class="comment">         * propagate one step, since FSG contains transitive closure of null</span>
<a name="l00762"></a>00762 <span class="comment">         * transitions.)</span>
<a name="l00763"></a>00763 <span class="comment">         */</span>
<a name="l00764"></a>00764         <span class="comment">/* Add all links from from_state to dst */</span>
<a name="l00765"></a>00765         <span class="keywordflow">for</span> (itor = fsg_model_arcs(fsg, s); itor;
<a name="l00766"></a>00766              itor = fsg_arciter_next(itor)) {
<a name="l00767"></a>00767             fsg_link_t *l = fsg_arciter_get(itor);
<a name="l00768"></a>00768 
<a name="l00769"></a>00769             <span class="comment">/* FIXME: Need to deal with tag transitions somehow. */</span>
<a name="l00770"></a>00770             <span class="keywordflow">if</span> (fsg_link_wid(l) != -1)
<a name="l00771"></a>00771                 <span class="keywordflow">continue</span>;
<a name="l00772"></a>00772             newscore =
<a name="l00773"></a>00773                 fsg_hist_entry_score(hist_entry) +
<a name="l00774"></a>00774                 (fsg_link_logs2prob(l) &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>);
<a name="l00775"></a>00775 
<a name="l00776"></a>00776             <span class="keywordflow">if</span> (newscore &gt;= thresh) {
<a name="l00777"></a>00777                 fsg_history_entry_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, l,
<a name="l00778"></a>00778                                       fsg_hist_entry_frame(hist_entry),
<a name="l00779"></a>00779                                       newscore,
<a name="l00780"></a>00780                                       bpidx,
<a name="l00781"></a>00781                                       fsg_hist_entry_lc(hist_entry),
<a name="l00782"></a>00782                                       fsg_hist_entry_rc(hist_entry));
<a name="l00783"></a>00783             }
<a name="l00784"></a>00784         }
<a name="l00785"></a>00785     }
<a name="l00786"></a>00786 }
<a name="l00787"></a>00787 
<a name="l00788"></a>00788 
<a name="l00789"></a>00789 <span class="comment">/*</span>
<a name="l00790"></a>00790 <span class="comment"> * Perform cross-word transitions; propagate each history entry created in this</span>
<a name="l00791"></a>00791 <span class="comment"> * frame to lextree roots attached to the target FSG state for that entry.</span>
<a name="l00792"></a>00792 <span class="comment"> */</span>
<a name="l00793"></a>00793 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00794"></a>00794 fsg_search_word_trans(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs)
<a name="l00795"></a>00795 {
<a name="l00796"></a>00796     int32 bpidx, n_entries;
<a name="l00797"></a>00797     <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry;
<a name="l00798"></a>00798     fsg_link_t *l;
<a name="l00799"></a>00799     int32 score, newscore, thresh, nf, d;
<a name="l00800"></a>00800     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *root;
<a name="l00801"></a>00801     int32 lc, rc;
<a name="l00802"></a>00802 
<a name="l00803"></a>00803     n_entries = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00804"></a>00804 
<a name="l00805"></a>00805     thresh = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> + fsgs-&gt;beam;
<a name="l00806"></a>00806     nf = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> + 1;
<a name="l00807"></a>00807 
<a name="l00808"></a>00808     <span class="keywordflow">for</span> (bpidx = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a24d59609008ac132dca256d36a89f9c8" title="First history entry index this frame.">bpidx_start</a>; bpidx &lt; n_entries; bpidx++) {
<a name="l00809"></a>00809         hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bpidx);
<a name="l00810"></a>00810         assert(hist_entry);
<a name="l00811"></a>00811         score = fsg_hist_entry_score(hist_entry);
<a name="l00812"></a>00812         assert(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> == fsg_hist_entry_frame(hist_entry));
<a name="l00813"></a>00813 
<a name="l00814"></a>00814         l = fsg_hist_entry_fsglink(hist_entry);
<a name="l00815"></a>00815 
<a name="l00816"></a>00816         <span class="comment">/* Destination state for hist_entry */</span>
<a name="l00817"></a>00817         d = l ? fsg_link_to_state(l) : fsg_model_start_state(fsgs-&gt;
<a name="l00818"></a>00818                                                                 fsg);
<a name="l00819"></a>00819 
<a name="l00820"></a>00820         lc = fsg_hist_entry_lc(hist_entry);
<a name="l00821"></a>00821 
<a name="l00822"></a>00822         <span class="comment">/* Transition to all root nodes attached to state d */</span>
<a name="l00823"></a>00823         <span class="keywordflow">for</span> (root = fsg_lextree_root(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ac2c756ff6c1a2f1059011756d22441f8" title="Lextree structure for the currently active FSG.">lextree</a>, d);
<a name="l00824"></a>00824              root; root = root-&gt;sibling) {
<a name="l00825"></a>00825             rc = root-&gt;ci_ext;
<a name="l00826"></a>00826 
<a name="l00827"></a>00827             <span class="keywordflow">if</span> ((root-&gt;ctxt.bv[lc &gt;&gt; 5] &amp; (1 &lt;&lt; (lc &amp; 0x001f))) &amp;&amp;
<a name="l00828"></a>00828                 (hist_entry-&gt;rc.bv[rc &gt;&gt; 5] &amp; (1 &lt;&lt; (rc &amp; 0x001f)))) {
<a name="l00829"></a>00829                 <span class="comment">/*</span>
<a name="l00830"></a>00830 <span class="comment">                 * Last CIphone of history entry is in left-context list supported by</span>
<a name="l00831"></a>00831 <span class="comment">                 * target root node, and</span>
<a name="l00832"></a>00832 <span class="comment">                 * first CIphone of target root node is in right context list supported</span>
<a name="l00833"></a>00833 <span class="comment">                 * by history entry;</span>
<a name="l00834"></a>00834 <span class="comment">                 * So the transition can go ahead (if new score is good enough).</span>
<a name="l00835"></a>00835 <span class="comment">                 */</span>
<a name="l00836"></a>00836                 newscore = score + root-&gt;logs2prob;
<a name="l00837"></a>00837 
<a name="l00838"></a>00838                 <span class="keywordflow">if</span> ((newscore <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> thresh)
<a name="l00839"></a>00839                     &amp;&amp; (newscore <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> hmm_in_score(&amp;root-&gt;hmm))) {
<a name="l00840"></a>00840                     <span class="keywordflow">if</span> (hmm_frame(&amp;root-&gt;hmm) &lt; nf) {
<a name="l00841"></a>00841                         <span class="comment">/* Newly activated node; add to active list */</span>
<a name="l00842"></a>00842                         fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> =
<a name="l00843"></a>00843                             glist_add_ptr(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>,
<a name="l00844"></a>00844                                           (<span class="keywordtype">void</span> *) root);
<a name="l00845"></a>00845 <span class="preprocessor">#if __FSG_DBG__</span>
<a name="l00846"></a>00846 <span class="preprocessor"></span>                        E_INFO
<a name="l00847"></a>00847                             (<span class="stringliteral">&quot;[%5d] WordTrans bpidx[%d] -&gt; pnode[%08x] (activated)\n&quot;</span>,
<a name="l00848"></a>00848                              fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, bpidx, (int32) root);
<a name="l00849"></a>00849 <span class="preprocessor">#endif</span>
<a name="l00850"></a>00850 <span class="preprocessor"></span>                    }
<a name="l00851"></a>00851                     <span class="keywordflow">else</span> {
<a name="l00852"></a>00852 <span class="preprocessor">#if __FSG_DBG__</span>
<a name="l00853"></a>00853 <span class="preprocessor"></span>                        E_INFO
<a name="l00854"></a>00854                             (<span class="stringliteral">&quot;[%5d] WordTrans bpidx[%d] -&gt; pnode[%08x]\n&quot;</span>,
<a name="l00855"></a>00855                              fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, bpidx, (int32) root);
<a name="l00856"></a>00856 <span class="preprocessor">#endif</span>
<a name="l00857"></a>00857 <span class="preprocessor"></span>                    }
<a name="l00858"></a>00858 
<a name="l00859"></a>00859                     hmm_enter(&amp;root-&gt;hmm, newscore, bpidx, nf);
<a name="l00860"></a>00860                 }
<a name="l00861"></a>00861             }
<a name="l00862"></a>00862         }
<a name="l00863"></a>00863     }
<a name="l00864"></a>00864 }
<a name="l00865"></a>00865 
<a name="l00866"></a>00866 
<a name="l00867"></a>00867 <span class="keywordtype">int</span>
<a name="l00868"></a>00868 fsg_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="l00869"></a>00869 {
<a name="l00870"></a>00870     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l00871"></a>00871     int16 <span class="keyword">const</span> *senscr;
<a name="l00872"></a>00872     <a class="code" href="structacmod__s.html" title="Acoustic model structure.">acmod_t</a> *acmod = search-&gt;<a class="code" href="structps__search__s.html#a0fdf6fe8c4d9c28f10c48c09517c6b91" title="Acoustic model.">acmod</a>;
<a name="l00873"></a>00873     gnode_t *gn;
<a name="l00874"></a>00874     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *pnode;
<a name="l00875"></a>00875     <a class="code" href="structhmm__t.html" title="An individual HMM among the HMM search space.">hmm_t</a> *hmm;
<a name="l00876"></a>00876 
<a name="l00877"></a>00877     <span class="comment">/* Activate our HMMs for the current frame if need be. */</span>
<a name="l00878"></a>00878     <span class="keywordflow">if</span> (!acmod-&gt;<a class="code" href="structacmod__s.html#ac08227365e3ed4354e26f013bc0df2bd" title="Compute all senones?">compallsen</a>)
<a name="l00879"></a>00879         fsg_search_sen_active(fsgs);
<a name="l00880"></a>00880     <span class="comment">/* Compute GMM scores for the current frame. */</span>
<a name="l00881"></a>00881     senscr = <a class="code" href="acmod_8c.html#acd78e9bae06724df9c53f844d90c1c8a" title="Score one frame of data.">acmod_score</a>(acmod, &amp;frame_idx);
<a name="l00882"></a>00882     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a56494e3b30d0c66367c7ef055b8addb2" title="Total senones evaluated this utt.">n_sen_eval</a> += acmod-&gt;<a class="code" href="structacmod__s.html#a5081a507e3ca6de6c5695217245dc9f9" title="Number of active GMMs.">n_senone_active</a>;
<a name="l00883"></a>00883     <a class="code" href="hmm_8h.html#a44d0b5515cb269bf9b95f62aada18cbb" title="Change the senone score array for a context.">hmm_context_set_senscore</a>(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7407bdf5f311caf9d46817b3387b798c" title="HMM context.">hmmctx</a>, senscr);
<a name="l00884"></a>00884 
<a name="l00885"></a>00885     <span class="comment">/* Mark backpointer table for current frame. */</span>
<a name="l00886"></a>00886     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a24d59609008ac132dca256d36a89f9c8" title="First history entry index this frame.">bpidx_start</a> = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00887"></a>00887 
<a name="l00888"></a>00888     <span class="comment">/* Evaluate all active pnodes (HMMs) */</span>
<a name="l00889"></a>00889     fsg_search_hmm_eval(fsgs);
<a name="l00890"></a>00890 
<a name="l00891"></a>00891     <span class="comment">/*</span>
<a name="l00892"></a>00892 <span class="comment">     * Prune and propagate the HMMs evaluated; create history entries for</span>
<a name="l00893"></a>00893 <span class="comment">     * word exits.  The words exits are tentative, and may be pruned; make</span>
<a name="l00894"></a>00894 <span class="comment">     * the survivors permanent via fsg_history_end_frame().</span>
<a name="l00895"></a>00895 <span class="comment">     */</span>
<a name="l00896"></a>00896     fsg_search_hmm_prune_prop(fsgs);
<a name="l00897"></a>00897     fsg_history_end_frame(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00898"></a>00898 
<a name="l00899"></a>00899     <span class="comment">/*</span>
<a name="l00900"></a>00900 <span class="comment">     * Propagate new history entries through any null transitions, creating</span>
<a name="l00901"></a>00901 <span class="comment">     * new history entries, and then make the survivors permanent.</span>
<a name="l00902"></a>00902 <span class="comment">     */</span>
<a name="l00903"></a>00903     fsg_search_null_prop(fsgs);
<a name="l00904"></a>00904     fsg_history_end_frame(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00905"></a>00905 
<a name="l00906"></a>00906     <span class="comment">/*</span>
<a name="l00907"></a>00907 <span class="comment">     * Perform cross-word transitions; propagate each history entry across its</span>
<a name="l00908"></a>00908 <span class="comment">     * terminating state to the root nodes of the lextree attached to the state.</span>
<a name="l00909"></a>00909 <span class="comment">     */</span>
<a name="l00910"></a>00910     fsg_search_word_trans(fsgs);
<a name="l00911"></a>00911 
<a name="l00912"></a>00912     <span class="comment">/*</span>
<a name="l00913"></a>00913 <span class="comment">     * We&#39;ve now come full circle, HMM and FSG states have been updated for</span>
<a name="l00914"></a>00914 <span class="comment">     * the next frame.</span>
<a name="l00915"></a>00915 <span class="comment">     * Update the active lists, deactivate any currently active HMMs that</span>
<a name="l00916"></a>00916 <span class="comment">     * did not survive into the next frame</span>
<a name="l00917"></a>00917 <span class="comment">     */</span>
<a name="l00918"></a>00918     <span class="keywordflow">for</span> (gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>; gn; gn = gnode_next(gn)) {
<a name="l00919"></a>00919         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l00920"></a>00920         hmm = fsg_pnode_hmmptr(pnode);
<a name="l00921"></a>00921 
<a name="l00922"></a>00922         <span class="keywordflow">if</span> (hmm_frame(hmm) == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>) {
<a name="l00923"></a>00923             <span class="comment">/* This HMM NOT activated for the next frame; reset it */</span>
<a name="l00924"></a>00924             <a class="code" href="fsg__lextree_8c.html#a6dc55ff3873855fb7b2c0390aa072516" title="Mark the given pnode as inactive (for search).">fsg_psubtree_pnode_deactivate</a>(pnode);
<a name="l00925"></a>00925         }
<a name="l00926"></a>00926         <span class="keywordflow">else</span> {
<a name="l00927"></a>00927             assert(hmm_frame(hmm) == (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> + 1));
<a name="l00928"></a>00928         }
<a name="l00929"></a>00929     }
<a name="l00930"></a>00930 
<a name="l00931"></a>00931     <span class="comment">/* Free the currently active list */</span>
<a name="l00932"></a>00932     glist_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>);
<a name="l00933"></a>00933 
<a name="l00934"></a>00934     <span class="comment">/* Make the next-frame active list the current one */</span>
<a name="l00935"></a>00935     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a> = fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>;
<a name="l00936"></a>00936     fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> = NULL;
<a name="l00937"></a>00937 
<a name="l00938"></a>00938     <span class="comment">/* End of this frame; ready for the next */</span>
<a name="l00939"></a>00939     ++fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>;
<a name="l00940"></a>00940 
<a name="l00941"></a>00941     <span class="keywordflow">return</span> 1;
<a name="l00942"></a>00942 }
<a name="l00943"></a>00943 
<a name="l00944"></a>00944 
<a name="l00945"></a>00945 <span class="comment">/*</span>
<a name="l00946"></a>00946 <span class="comment"> * Set all HMMs to inactive, clear active lists, initialize FSM start</span>
<a name="l00947"></a>00947 <span class="comment"> * state to be the only active node.</span>
<a name="l00948"></a>00948 <span class="comment"> * (Executed at the start of each utterance.)</span>
<a name="l00949"></a>00949 <span class="comment"> */</span>
<a name="l00950"></a>00950 <span class="keywordtype">int</span>
<a name="l00951"></a>00951 fsg_search_start(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l00952"></a>00952 {
<a name="l00953"></a>00953     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l00954"></a>00954     int32 silcipid;
<a name="l00955"></a>00955     <a class="code" href="structfsg__pnode__ctxt__t.html">fsg_pnode_ctxt_t</a> ctxt;
<a name="l00956"></a>00956 
<a name="l00957"></a>00957     <span class="comment">/* Reset dynamic adjustment factor for beams */</span>
<a name="l00958"></a>00958     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a8e86d9f82189f8429d71ee2f67ecaaa2" title="Dynamic/adaptive factor (&amp;lt;=1) applied to above beams to determine actual effective beams...">beam_factor</a> = 1.0f;
<a name="l00959"></a>00959     fsgs-&gt;beam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a0cdf7dc3d3eed0d37f46cb71fdea206e" title="Global pruning threshold.">beam_orig</a>;
<a name="l00960"></a>00960     fsgs-&gt;pbeam = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7cdf0ab2591b95d89940d51e3ab01529" title="Pruning threshold for phone transition.">pbeam_orig</a>;
<a name="l00961"></a>00961     fsgs-&gt;<a class="code" href="structfsg__search__s.html#af28ddecbb5115a50712c61f8a72dcf51" title="Effective beams after applying beam_factor.">wbeam</a> = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7f3ecc2f769143e42ed958744478db3c" title="Pruning threshold for word exit.">wbeam_orig</a>;
<a name="l00962"></a>00962 
<a name="l00963"></a>00963     silcipid = bin_mdef_ciphone_id(ps_search_acmod(fsgs)-&gt;mdef, <span class="stringliteral">&quot;SIL&quot;</span>);
<a name="l00964"></a>00964 
<a name="l00965"></a>00965     <span class="comment">/* Initialize EVERYTHING to be inactive */</span>
<a name="l00966"></a>00966     assert(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a> == NULL);
<a name="l00967"></a>00967     assert(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> == NULL);
<a name="l00968"></a>00968 
<a name="l00969"></a>00969     fsg_history_reset(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00970"></a>00970     fsg_history_utt_start(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l00971"></a>00971     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a> = FALSE;
<a name="l00972"></a>00972 
<a name="l00973"></a>00973     <span class="comment">/* Dummy context structure that allows all right contexts to use this entry */</span>
<a name="l00974"></a>00974     <a class="code" href="fsg__lextree_8c.html#a98fd94d024df264025e30c909c82cb56" title="Set all flags on in the given context bitvector.">fsg_pnode_add_all_ctxt</a>(&amp;ctxt);
<a name="l00975"></a>00975 
<a name="l00976"></a>00976     <span class="comment">/* Create dummy history entry leading to start state */</span>
<a name="l00977"></a>00977     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> = -1;
<a name="l00978"></a>00978     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a52880ad440412d76f7aae7e05977ba4b" title="For beam pruning.">bestscore</a> = 0;
<a name="l00979"></a>00979     fsg_history_entry_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>,
<a name="l00980"></a>00980                           NULL, -1, 0, -1, silcipid, ctxt);
<a name="l00981"></a>00981     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a24d59609008ac132dca256d36a89f9c8" title="First history entry index this frame.">bpidx_start</a> = 0;
<a name="l00982"></a>00982 
<a name="l00983"></a>00983     <span class="comment">/* Propagate dummy history entry through NULL transitions from start state */</span>
<a name="l00984"></a>00984     fsg_search_null_prop(fsgs);
<a name="l00985"></a>00985 
<a name="l00986"></a>00986     <span class="comment">/* Perform word transitions from this dummy history entry */</span>
<a name="l00987"></a>00987     fsg_search_word_trans(fsgs);
<a name="l00988"></a>00988 
<a name="l00989"></a>00989     <span class="comment">/* Make the next-frame active list the current one */</span>
<a name="l00990"></a>00990     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a> = fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>;
<a name="l00991"></a>00991     fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> = NULL;
<a name="l00992"></a>00992 
<a name="l00993"></a>00993     ++fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>;
<a name="l00994"></a>00994 
<a name="l00995"></a>00995     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7e3d7375b4a33af339e8b55885677faa" title="Total HMMs evaluated this utt.">n_hmm_eval</a> = 0;
<a name="l00996"></a>00996     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a56494e3b30d0c66367c7ef055b8addb2" title="Total senones evaluated this utt.">n_sen_eval</a> = 0;
<a name="l00997"></a>00997 
<a name="l00998"></a>00998     <span class="keywordflow">return</span> 0;
<a name="l00999"></a>00999 }
<a name="l01000"></a>01000 
<a name="l01001"></a>01001 <span class="comment">/*</span>
<a name="l01002"></a>01002 <span class="comment"> * Cleanup at the end of each utterance.</span>
<a name="l01003"></a>01003 <span class="comment"> */</span>
<a name="l01004"></a>01004 <span class="keywordtype">int</span>
<a name="l01005"></a>01005 fsg_search_finish(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l01006"></a>01006 {
<a name="l01007"></a>01007     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01008"></a>01008     gnode_t *gn;
<a name="l01009"></a>01009     <a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *pnode;
<a name="l01010"></a>01010     int32 n_hist;
<a name="l01011"></a>01011 
<a name="l01012"></a>01012     <span class="comment">/* Deactivate all nodes in the current and next-frame active lists */</span>
<a name="l01013"></a>01013     <span class="keywordflow">for</span> (gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>; gn; gn = gnode_next(gn)) {
<a name="l01014"></a>01014         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l01015"></a>01015         <a class="code" href="fsg__lextree_8c.html#a6dc55ff3873855fb7b2c0390aa072516" title="Mark the given pnode as inactive (for search).">fsg_psubtree_pnode_deactivate</a>(pnode);
<a name="l01016"></a>01016     }
<a name="l01017"></a>01017     <span class="keywordflow">for</span> (gn = fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>; gn; gn = gnode_next(gn)) {
<a name="l01018"></a>01018         pnode = (<a class="code" href="structfsg__pnode__s.html">fsg_pnode_t</a> *) gnode_ptr(gn);
<a name="l01019"></a>01019         <a class="code" href="fsg__lextree_8c.html#a6dc55ff3873855fb7b2c0390aa072516" title="Mark the given pnode as inactive (for search).">fsg_psubtree_pnode_deactivate</a>(pnode);
<a name="l01020"></a>01020     }
<a name="l01021"></a>01021 
<a name="l01022"></a>01022     glist_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a>);
<a name="l01023"></a>01023     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a318ff42978c1e645f01962345ac08215" title="Those active in this frame.">pnode_active</a> = NULL;
<a name="l01024"></a>01024     glist_free(fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a>);
<a name="l01025"></a>01025     fsgs-&gt;<a class="code" href="structfsg__search__s.html#aa2dfc00e1f34041dacd9572b0d659775" title="Those activated for the next frame.">pnode_active_next</a> = NULL;
<a name="l01026"></a>01026 
<a name="l01027"></a>01027     fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a> = TRUE;
<a name="l01028"></a>01028 
<a name="l01029"></a>01029     n_hist = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l01030"></a>01030     E_INFO
<a name="l01031"></a>01031         (<span class="stringliteral">&quot;%d frames, %d HMMs (%d/fr), %d senones (%d/fr), %d history entries (%d/fr)\n\n&quot;</span>,
<a name="l01032"></a>01032          fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7e3d7375b4a33af339e8b55885677faa" title="Total HMMs evaluated this utt.">n_hmm_eval</a>,
<a name="l01033"></a>01033          (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> &gt; 0) ? fsgs-&gt;<a class="code" href="structfsg__search__s.html#a7e3d7375b4a33af339e8b55885677faa" title="Total HMMs evaluated this utt.">n_hmm_eval</a> / fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> : 0,
<a name="l01034"></a>01034          fsgs-&gt;<a class="code" href="structfsg__search__s.html#a56494e3b30d0c66367c7ef055b8addb2" title="Total senones evaluated this utt.">n_sen_eval</a>,
<a name="l01035"></a>01035          (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> &gt; 0) ? fsgs-&gt;<a class="code" href="structfsg__search__s.html#a56494e3b30d0c66367c7ef055b8addb2" title="Total senones evaluated this utt.">n_sen_eval</a> / fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> : 0,
<a name="l01036"></a>01036          n_hist, (fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> &gt; 0) ? n_hist / fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> : 0);
<a name="l01037"></a>01037 
<a name="l01038"></a>01038     <span class="keywordflow">return</span> 0;
<a name="l01039"></a>01039 }
<a name="l01040"></a>01040 
<a name="l01041"></a>01041 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l01042"></a>01042 fsg_search_find_exit(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <span class="keywordtype">int</span> frame_idx, <span class="keywordtype">int</span> <span class="keyword">final</span>, int32 *out_score)
<a name="l01043"></a>01043 {
<a name="l01044"></a>01044     <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry;
<a name="l01045"></a>01045     fsg_model_t *fsg;
<a name="l01046"></a>01046     <span class="keywordtype">int</span> bpidx, frm, last_frm, besthist;
<a name="l01047"></a>01047     int32 bestscore;
<a name="l01048"></a>01048 
<a name="l01049"></a>01049     <span class="keywordflow">if</span> (frame_idx == -1)
<a name="l01050"></a>01050         frame_idx = fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a> - 1;
<a name="l01051"></a>01051     last_frm = frm = frame_idx;
<a name="l01052"></a>01052 
<a name="l01053"></a>01053     <span class="comment">/* Scan backwards to find a word exit in frame_idx. */</span>
<a name="l01054"></a>01054     bpidx = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>) - 1;
<a name="l01055"></a>01055     <span class="keywordflow">while</span> (bpidx &gt; 0) {
<a name="l01056"></a>01056         hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bpidx);
<a name="l01057"></a>01057         <span class="keywordflow">if</span> (fsg_hist_entry_frame(hist_entry) &lt;= frame_idx) {
<a name="l01058"></a>01058             frm = last_frm = fsg_hist_entry_frame(hist_entry);
<a name="l01059"></a>01059             <span class="keywordflow">break</span>;
<a name="l01060"></a>01060         }
<a name="l01061"></a>01061     }
<a name="l01062"></a>01062 
<a name="l01063"></a>01063     <span class="comment">/* No hypothesis (yet). */</span>
<a name="l01064"></a>01064     <span class="keywordflow">if</span> (bpidx &lt;= 0) 
<a name="l01065"></a>01065         <span class="keywordflow">return</span> bpidx;
<a name="l01066"></a>01066 
<a name="l01067"></a>01067     <span class="comment">/* Now find best word exit in this frame. */</span>
<a name="l01068"></a>01068     bestscore = INT_MIN;
<a name="l01069"></a>01069     besthist = -1;
<a name="l01070"></a>01070     fsg = fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>;
<a name="l01071"></a>01071     <span class="keywordflow">while</span> (frm == last_frm) {
<a name="l01072"></a>01072         fsg_link_t *fl;
<a name="l01073"></a>01073         int32 score;
<a name="l01074"></a>01074 
<a name="l01075"></a>01075         fl = fsg_hist_entry_fsglink(hist_entry);
<a name="l01076"></a>01076         score = fsg_hist_entry_score(hist_entry);
<a name="l01077"></a>01077         
<a name="l01078"></a>01078         <span class="keywordflow">if</span> (fl == NULL)
<a name="l01079"></a>01079             <span class="keywordflow">break</span>;
<a name="l01080"></a>01080 
<a name="l01081"></a>01081         <span class="keywordflow">if</span> (score <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> bestscore) {
<a name="l01082"></a>01082             <span class="comment">/* Only enforce the final state constraint if this is a final hypothesis. */</span>
<a name="l01083"></a>01083             <span class="keywordflow">if</span> ((!<span class="keyword">final</span>)
<a name="l01084"></a>01084                 || fsg_link_to_state(fl) == fsg_model_final_state(fsg)) {
<a name="l01085"></a>01085                 bestscore = score;
<a name="l01086"></a>01086                 besthist = bpidx;
<a name="l01087"></a>01087             }
<a name="l01088"></a>01088         }
<a name="l01089"></a>01089 
<a name="l01090"></a>01090         --bpidx;
<a name="l01091"></a>01091         <span class="keywordflow">if</span> (bpidx &lt; 0)
<a name="l01092"></a>01092             <span class="keywordflow">break</span>;
<a name="l01093"></a>01093         hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bpidx);
<a name="l01094"></a>01094         frm = fsg_hist_entry_frame(hist_entry);
<a name="l01095"></a>01095     }
<a name="l01096"></a>01096 
<a name="l01097"></a>01097     <span class="comment">/* Final state not reached. */</span>
<a name="l01098"></a>01098     <span class="keywordflow">if</span> (besthist == -1) {
<a name="l01099"></a>01099         E_ERROR(<span class="stringliteral">&quot;Final state not reached in frame %d\n&quot;</span>, frame_idx);
<a name="l01100"></a>01100         <span class="keywordflow">return</span> -1;
<a name="l01101"></a>01101     }
<a name="l01102"></a>01102 
<a name="l01103"></a>01103     <span class="comment">/* This here&#39;s the one we want. */</span>
<a name="l01104"></a>01104     <span class="keywordflow">if</span> (out_score)
<a name="l01105"></a>01105         *out_score = bestscore;
<a name="l01106"></a>01106     <span class="keywordflow">return</span> besthist;
<a name="l01107"></a>01107 }
<a name="l01108"></a>01108 
<a name="l01109"></a>01109 <span class="comment">/* FIXME: Mostly duplicated with ngram_search_bestpath(). */</span>
<a name="l01110"></a>01110 <span class="keyword">static</span> <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *
<a name="l01111"></a>01111 fsg_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="l01112"></a>01112 {
<a name="l01113"></a>01113     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01114"></a>01114 
<a name="l01115"></a>01115     <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="l01116"></a>01116         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>, NULL,
<a name="l01117"></a>01117                                                 1.0, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a4d13fff2e14882b0125386fc27a4097f" title="Acoustic score scale for posterior probabilities.">ascale</a>);
<a name="l01118"></a>01118         <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="l01119"></a>01119             <span class="keywordflow">return</span> NULL;
<a name="l01120"></a>01120         <span class="comment">/* Also calculate betas so we can fill in the posterior</span>
<a name="l01121"></a>01121 <span class="comment">         * probability field in the segmentation. */</span>
<a name="l01122"></a>01122         <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="l01123"></a>01123             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>, NULL, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a4d13fff2e14882b0125386fc27a4097f" title="Acoustic score scale for posterior probabilities.">ascale</a>);
<a name="l01124"></a>01124     }
<a name="l01125"></a>01125     <span class="keywordflow">if</span> (out_score)
<a name="l01126"></a>01126         *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="l01127"></a>01127     <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="l01128"></a>01128 }
<a name="l01129"></a>01129 
<a name="l01130"></a>01130 <span class="keywordtype">char</span> <span class="keyword">const</span> *
<a name="l01131"></a>01131 fsg_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="l01132"></a>01132 {
<a name="l01133"></a>01133     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01134"></a>01134     <a class="code" href="structdict__t.html" title="a structure for a dictionary.">dict_t</a> *dict = ps_search_dict(search);
<a name="l01135"></a>01135     <span class="keywordtype">char</span> *c;
<a name="l01136"></a>01136     <span class="keywordtype">size_t</span> len;
<a name="l01137"></a>01137     <span class="keywordtype">int</span> bp, bpidx;
<a name="l01138"></a>01138 
<a name="l01139"></a>01139     <span class="comment">/* Get last backpointer table index. */</span>
<a name="l01140"></a>01140     bpidx = fsg_search_find_exit(fsgs, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a>, out_score);
<a name="l01141"></a>01141     <span class="comment">/* No hypothesis (yet). */</span>
<a name="l01142"></a>01142     <span class="keywordflow">if</span> (bpidx &lt;= 0)
<a name="l01143"></a>01143         <span class="keywordflow">return</span> NULL;
<a name="l01144"></a>01144 
<a name="l01145"></a>01145     <span class="comment">/* If bestpath is enabled and the utterance is complete, then run it. */</span>
<a name="l01146"></a>01146     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#aba7eff57919c5a1de55eab3a62ff055a" title="Whether to run bestpath search and confidence annotation at end.">bestpath</a> &amp;&amp; fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a>) {
<a name="l01147"></a>01147         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01148"></a>01148         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l01149"></a>01149 
<a name="l01150"></a>01150         <span class="keywordflow">if</span> ((dag = fsg_search_lattice(search)) == NULL) {
<a name="l01151"></a>01151             E_WARN(<span class="stringliteral">&quot;Failed to obtain the lattice while bestpath enabled\n&quot;</span>);
<a name="l01152"></a>01152             <span class="keywordflow">return</span> NULL;
<a name="l01153"></a>01153         }
<a name="l01154"></a>01154         <span class="keywordflow">if</span> ((link = fsg_search_bestpath(search, out_score, FALSE)) == NULL) {
<a name="l01155"></a>01155             E_WARN(<span class="stringliteral">&quot;Failed to bestpath in a lattice\n&quot;</span>);
<a name="l01156"></a>01156             <span class="keywordflow">return</span> NULL;
<a name="l01157"></a>01157         }
<a name="l01158"></a>01158         <span class="keywordflow">return</span> <a class="code" href="ps__lattice_8c.html#a02b07c009d23b852bd4db54700dfac5b" title="Get hypothesis string after bestpath search.">ps_lattice_hyp</a>(dag, link);
<a name="l01159"></a>01159     }
<a name="l01160"></a>01160 
<a name="l01161"></a>01161     bp = bpidx;
<a name="l01162"></a>01162     len = 0;
<a name="l01163"></a>01163     <span class="keywordflow">while</span> (bp &gt; 0) {
<a name="l01164"></a>01164         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bp);
<a name="l01165"></a>01165         fsg_link_t *fl = fsg_hist_entry_fsglink(hist_entry);
<a name="l01166"></a>01166         <span class="keywordtype">char</span> <span class="keyword">const</span> *baseword;
<a name="l01167"></a>01167         int32 wid;
<a name="l01168"></a>01168 
<a name="l01169"></a>01169         bp = fsg_hist_entry_pred(hist_entry);
<a name="l01170"></a>01170         wid = fsg_link_wid(fl);
<a name="l01171"></a>01171         <span class="keywordflow">if</span> (wid &lt; 0 || fsg_model_is_filler(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid))
<a name="l01172"></a>01172             <span class="keywordflow">continue</span>;
<a name="l01173"></a>01173         baseword = dict_basestr(dict,
<a name="l01174"></a>01174                                 dict_wordid(dict,
<a name="l01175"></a>01175                                             fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid)));
<a name="l01176"></a>01176         len += strlen(baseword) + 1;
<a name="l01177"></a>01177     }
<a name="l01178"></a>01178     
<a name="l01179"></a>01179     ckd_free(search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>);
<a name="l01180"></a>01180     <span class="keywordflow">if</span> (len == 0) {
<a name="l01181"></a>01181         search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> = NULL;
<a name="l01182"></a>01182         <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>;
<a name="l01183"></a>01183     }
<a name="l01184"></a>01184     search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> = ckd_calloc(1, len);
<a name="l01185"></a>01185 
<a name="l01186"></a>01186     bp = bpidx;
<a name="l01187"></a>01187     c = search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a> + len - 1;
<a name="l01188"></a>01188     <span class="keywordflow">while</span> (bp &gt; 0) {
<a name="l01189"></a>01189         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bp);
<a name="l01190"></a>01190         fsg_link_t *fl = fsg_hist_entry_fsglink(hist_entry);
<a name="l01191"></a>01191         <span class="keywordtype">char</span> <span class="keyword">const</span> *baseword;
<a name="l01192"></a>01192         int32 wid;
<a name="l01193"></a>01193 
<a name="l01194"></a>01194         bp = fsg_hist_entry_pred(hist_entry);
<a name="l01195"></a>01195         wid = fsg_link_wid(fl);
<a name="l01196"></a>01196         <span class="keywordflow">if</span> (wid &lt; 0 || fsg_model_is_filler(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid))
<a name="l01197"></a>01197             <span class="keywordflow">continue</span>;
<a name="l01198"></a>01198         baseword = dict_basestr(dict,
<a name="l01199"></a>01199                                 dict_wordid(dict,
<a name="l01200"></a>01200                                             fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, wid)));
<a name="l01201"></a>01201         len = strlen(baseword);
<a name="l01202"></a>01202         c -= len;
<a name="l01203"></a>01203         memcpy(c, baseword, len);
<a name="l01204"></a>01204         <span class="keywordflow">if</span> (c &gt; search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>) {
<a name="l01205"></a>01205             --c;
<a name="l01206"></a>01206             *c = <span class="charliteral">&#39; &#39;</span>;
<a name="l01207"></a>01207         }
<a name="l01208"></a>01208     }
<a name="l01209"></a>01209 
<a name="l01210"></a>01210     <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#aa398c736a887af97e42b2a562359adc3" title="Current hypothesis string.">hyp_str</a>;
<a name="l01211"></a>01211 }
<a name="l01212"></a>01212 
<a name="l01213"></a>01213 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l01214"></a>01214 fsg_seg_bp2itor(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg, <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry)
<a name="l01215"></a>01215 {
<a name="l01216"></a>01216     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_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="l01217"></a>01217     <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *ph = NULL;
<a name="l01218"></a>01218     int32 bp;
<a name="l01219"></a>01219 
<a name="l01220"></a>01220     if ((bp = fsg_hist_entry_pred(hist_entry)) &gt;= 0)
<a name="l01221"></a>01221         ph = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bp);
<a name="l01222"></a>01222     seg-&gt;<a class="code" href="structps__seg__s.html#a97a0dc7db931c7e3f98d23d21ce27f04" title="Word string (pointer into dictionary hash)">word</a> = fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, hist_entry-&gt;fsglink-&gt;wid);
<a name="l01223"></a>01223     seg-&gt;<a class="code" href="structps__seg__s.html#a2043ca87b07df0cd80d0fb65c3521c04" title="End frame.">ef</a> = fsg_hist_entry_frame(hist_entry);
<a name="l01224"></a>01224     seg-&gt;<a class="code" href="structps__seg__s.html#ac292e31304906addf3d49f1473df8ead" title="Start frame.">sf</a> = ph ? fsg_hist_entry_frame(ph) + 1 : 0;
<a name="l01225"></a>01225     <span class="comment">/* This is kind of silly but it happens for null transitions. */</span>
<a name="l01226"></a>01226     <span class="keywordflow">if</span> (seg-&gt;<a class="code" href="structps__seg__s.html#ac292e31304906addf3d49f1473df8ead" title="Start frame.">sf</a> &gt; seg-&gt;<a class="code" href="structps__seg__s.html#a2043ca87b07df0cd80d0fb65c3521c04" title="End frame.">ef</a>) seg-&gt;<a class="code" href="structps__seg__s.html#ac292e31304906addf3d49f1473df8ead" title="Start frame.">sf</a> = seg-&gt;<a class="code" href="structps__seg__s.html#a2043ca87b07df0cd80d0fb65c3521c04" title="End frame.">ef</a>;
<a name="l01227"></a>01227     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="l01228"></a>01228     <span class="comment">/* &quot;Language model&quot; score = transition probability. */</span>
<a name="l01229"></a>01229     seg-&gt;<a class="code" href="structps__seg__s.html#a4d86c21f1ed2dc3eb3b1b1b37ce9bb48" title="Language model backoff.">lback</a> = 1;
<a name="l01230"></a>01230     seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a> = hist_entry-&gt;fsglink-&gt;logs2prob;
<a name="l01231"></a>01231     <span class="keywordflow">if</span> (ph) {
<a name="l01232"></a>01232         <span class="comment">/* FIXME: Not sure exactly how cross-word triphones are handled. */</span>
<a name="l01233"></a>01233         seg-&gt;<a class="code" href="structps__seg__s.html#a6f7706ec4c0d0ec8ecafaf0f29f41f4b" title="Acoustic score.">ascr</a> = hist_entry-&gt;score - ph-&gt;score - seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a>;
<a name="l01234"></a>01234     }
<a name="l01235"></a>01235     <span class="keywordflow">else</span>
<a name="l01236"></a>01236         seg-&gt;<a class="code" href="structps__seg__s.html#a6f7706ec4c0d0ec8ecafaf0f29f41f4b" title="Acoustic score.">ascr</a> = hist_entry-&gt;score - seg-&gt;<a class="code" href="structps__seg__s.html#a69e605f422eeed1a9c67437e8ddd8b08" title="Language model score.">lscr</a>;
<a name="l01237"></a>01237 }
<a name="l01238"></a>01238 
<a name="l01239"></a>01239 
<a name="l01240"></a>01240 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l01241"></a>01241 fsg_seg_free(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg)
<a name="l01242"></a>01242 {
<a name="l01243"></a>01243     <a class="code" href="structfsg__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for FSG history.">fsg_seg_t</a> *itor = (<a class="code" href="structfsg__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for FSG history.">fsg_seg_t</a> *)seg;
<a name="l01244"></a>01244     ckd_free(itor-&gt;<a class="code" href="structfsg__seg__s.html#ae41fbe837c6c921133c91453c58ba68e" title="Sequence of history entries.">hist</a>);
<a name="l01245"></a>01245     ckd_free(itor);
<a name="l01246"></a>01246 }
<a name="l01247"></a>01247 
<a name="l01248"></a>01248 <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="l01249"></a>01249 fsg_seg_next(<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *seg)
<a name="l01250"></a>01250 {
<a name="l01251"></a>01251     <a class="code" href="structfsg__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for FSG history.">fsg_seg_t</a> *itor = (<a class="code" href="structfsg__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for FSG history.">fsg_seg_t</a> *)seg;
<a name="l01252"></a>01252 
<a name="l01253"></a>01253     <span class="keywordflow">if</span> (++itor-&gt;<a class="code" href="structfsg__seg__s.html#a4b5e46bf79915c97845974e80355ebbe" title="Current position in hist.">cur</a> == itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a>) {
<a name="l01254"></a>01254         fsg_seg_free(seg);
<a name="l01255"></a>01255         <span class="keywordflow">return</span> NULL;
<a name="l01256"></a>01256     }
<a name="l01257"></a>01257 
<a name="l01258"></a>01258     fsg_seg_bp2itor(seg, itor-&gt;<a class="code" href="structfsg__seg__s.html#ae41fbe837c6c921133c91453c58ba68e" title="Sequence of history entries.">hist</a>[itor-&gt;<a class="code" href="structfsg__seg__s.html#a4b5e46bf79915c97845974e80355ebbe" title="Current position in hist.">cur</a>]);
<a name="l01259"></a>01259     <span class="keywordflow">return</span> seg;
<a name="l01260"></a>01260 }
<a name="l01261"></a>01261 
<a name="l01262"></a>01262 <span class="keyword">static</span> <a class="code" href="structps__segfuncs__s.html">ps_segfuncs_t</a> fsg_segfuncs = {
<a name="l01263"></a>01263     <span class="comment">/* seg_next */</span> fsg_seg_next,
<a name="l01264"></a>01264     <span class="comment">/* seg_free */</span> fsg_seg_free
<a name="l01265"></a>01265 };
<a name="l01266"></a>01266 
<a name="l01267"></a>01267 <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="l01268"></a>01268 fsg_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="l01269"></a>01269 {
<a name="l01270"></a>01270     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01271"></a>01271     <a class="code" href="structfsg__seg__s.html" title="Segmentation &amp;quot;iterator&amp;quot; for FSG history.">fsg_seg_t</a> *itor;
<a name="l01272"></a>01272     <span class="keywordtype">int</span> bp, bpidx, cur;
<a name="l01273"></a>01273 
<a name="l01274"></a>01274     bpidx = fsg_search_find_exit(fsgs, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a>, out_score);
<a name="l01275"></a>01275     <span class="comment">/* No hypothesis (yet). */</span>
<a name="l01276"></a>01276     <span class="keywordflow">if</span> (bpidx &lt;= 0)
<a name="l01277"></a>01277         <span class="keywordflow">return</span> NULL;
<a name="l01278"></a>01278 
<a name="l01279"></a>01279     <span class="comment">/* If bestpath is enabled and the utterance is complete, then run it. */</span>
<a name="l01280"></a>01280     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#aba7eff57919c5a1de55eab3a62ff055a" title="Whether to run bestpath search and confidence annotation at end.">bestpath</a> &amp;&amp; fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a>) {
<a name="l01281"></a>01281         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01282"></a>01282         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l01283"></a>01283 
<a name="l01284"></a>01284         <span class="keywordflow">if</span> ((dag = fsg_search_lattice(search)) == NULL)
<a name="l01285"></a>01285             <span class="keywordflow">return</span> NULL;
<a name="l01286"></a>01286         <span class="keywordflow">if</span> ((link = fsg_search_bestpath(search, out_score, TRUE)) == NULL)
<a name="l01287"></a>01287             <span class="keywordflow">return</span> NULL;
<a name="l01288"></a>01288         <span class="keywordflow">return</span> <a class="code" href="ps__lattice_8c.html#afedbc5558c18f7d029e84a4e27e38187" title="Get hypothesis segmentation iterator after bestpath search.">ps_lattice_seg_iter</a>(dag, link, 1.0);
<a name="l01289"></a>01289     }
<a name="l01290"></a>01290 
<a name="l01291"></a>01291     <span class="comment">/* Calling this an &quot;iterator&quot; is a bit of a misnomer since we have</span>
<a name="l01292"></a>01292 <span class="comment">     * to get the entire backtrace in order to produce it.  On the</span>
<a name="l01293"></a>01293 <span class="comment">     * other hand, all we actually need is the bptbl IDs, and we can</span>
<a name="l01294"></a>01294 <span class="comment">     * allocate a fixed-size array of them. */</span>
<a name="l01295"></a>01295     itor = ckd_calloc(1, <span class="keyword">sizeof</span>(*itor));
<a name="l01296"></a>01296     itor-&gt;<a class="code" href="structfsg__seg__s.html#a9f977be4814ec887aadb3cea35f96bab" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a510362a2281e374c839397c3e5488515" title="V-table of seg methods.">vt</a> = &amp;fsg_segfuncs;
<a name="l01297"></a>01297     itor-&gt;<a class="code" href="structfsg__seg__s.html#a9f977be4814ec887aadb3cea35f96bab" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a14168ddcb60e094dad36c7c920a79bb3" title="Search object from whence this came.">search</a> = search;
<a name="l01298"></a>01298     itor-&gt;<a class="code" href="structfsg__seg__s.html#a9f977be4814ec887aadb3cea35f96bab" title="Base structure.">base</a>.<a class="code" href="structps__seg__s.html#a2249c012b83c902f4f8ed8d98ded7d20" title="Language weight factor (for second-pass searches)">lwf</a> = 1.0;
<a name="l01299"></a>01299     itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a> = 0;
<a name="l01300"></a>01300     bp = bpidx;
<a name="l01301"></a>01301     <span class="keywordflow">while</span> (bp &gt; 0) {
<a name="l01302"></a>01302         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bp);
<a name="l01303"></a>01303         bp = fsg_hist_entry_pred(hist_entry);
<a name="l01304"></a>01304         ++itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a>;
<a name="l01305"></a>01305     }
<a name="l01306"></a>01306     <span class="keywordflow">if</span> (itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a> == 0) {
<a name="l01307"></a>01307         ckd_free(itor);
<a name="l01308"></a>01308         <span class="keywordflow">return</span> NULL;
<a name="l01309"></a>01309     }
<a name="l01310"></a>01310     itor-&gt;<a class="code" href="structfsg__seg__s.html#ae41fbe837c6c921133c91453c58ba68e" title="Sequence of history entries.">hist</a> = ckd_calloc(itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a>, <span class="keyword">sizeof</span>(*itor-&gt;<a class="code" href="structfsg__seg__s.html#ae41fbe837c6c921133c91453c58ba68e" title="Sequence of history entries.">hist</a>));
<a name="l01311"></a>01311     cur = itor-&gt;<a class="code" href="structfsg__seg__s.html#aca806a5b88f77803fff4c4c984034515" title="Number of history entries.">n_hist</a> - 1;
<a name="l01312"></a>01312     bp = bpidx;
<a name="l01313"></a>01313     <span class="keywordflow">while</span> (bp &gt; 0) {
<a name="l01314"></a>01314         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *hist_entry = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, bp);
<a name="l01315"></a>01315         itor-&gt;<a class="code" href="structfsg__seg__s.html#ae41fbe837c6c921133c91453c58ba68e" title="Sequence of history entries.">hist</a>[cur] = hist_entry;
<a name="l01316"></a>01316         bp = fsg_hist_entry_pred(hist_entry);
<a name="l01317"></a>01317         --cur;
<a name="l01318"></a>01318     }
<a name="l01319"></a>01319 
<a name="l01320"></a>01320     <span class="comment">/* Fill in relevant fields for first element. */</span>
<a name="l01321"></a>01321     fsg_seg_bp2itor((<a class="code" href="structps__seg__s.html" title="Base structure for hypothesis segmentation iterator.">ps_seg_t</a> *)itor, itor-&gt;hist[0]);
<a name="l01322"></a>01322     
<a name="l01323"></a>01323     <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="l01324"></a>01324 }
<a name="l01325"></a>01325 
<a name="l01326"></a>01326 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l01327"></a>01327 fsg_search_prob(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l01328"></a>01328 {
<a name="l01329"></a>01329     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01330"></a>01330 
<a name="l01331"></a>01331     <span class="comment">/* If bestpath is enabled and the utterance is complete, then run it. */</span>
<a name="l01332"></a>01332     <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#aba7eff57919c5a1de55eab3a62ff055a" title="Whether to run bestpath search and confidence annotation at end.">bestpath</a> &amp;&amp; fsgs-&gt;<a class="code" href="structfsg__search__s.html#a5139d7ab35ae18407e06e78e1778f857" title="Decoding is finished for this utterance.">final</a>) {
<a name="l01333"></a>01333         <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01334"></a>01334         <a class="code" href="structps__latlink__s.html" title="Links between DAG nodes.">ps_latlink_t</a> *link;
<a name="l01335"></a>01335 
<a name="l01336"></a>01336         <span class="keywordflow">if</span> ((dag = fsg_search_lattice(search)) == NULL)
<a name="l01337"></a>01337             <span class="keywordflow">return</span> 0;
<a name="l01338"></a>01338         <span class="keywordflow">if</span> ((link = fsg_search_bestpath(search, NULL, TRUE)) == NULL)
<a name="l01339"></a>01339             <span class="keywordflow">return</span> 0;
<a name="l01340"></a>01340         <span class="keywordflow">return</span> search-&gt;<a class="code" href="structps__search__s.html#a721a656d0e34f7604ea8c52a1bdf14ff" title="Utterance posterior probability.">post</a>;
<a name="l01341"></a>01341     }
<a name="l01342"></a>01342     <span class="keywordflow">else</span> {
<a name="l01343"></a>01343         <span class="comment">/* FIXME: Give some kind of good estimate here, eventually. */</span>
<a name="l01344"></a>01344         <span class="keywordflow">return</span> 0;
<a name="l01345"></a>01345     }
<a name="l01346"></a>01346 }
<a name="l01347"></a>01347 
<a name="l01348"></a>01348 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01349"></a>01349 new_node(<a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag, fsg_model_t *fsg, <span class="keywordtype">int</span> sf, <span class="keywordtype">int</span> ef, int32 wid, int32 ascr)
<a name="l01350"></a>01350 {
<a name="l01351"></a>01351     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01352"></a>01352 
<a name="l01353"></a>01353     <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="l01354"></a>01354         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == sf &amp;&amp; node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> == wid)
<a name="l01355"></a>01355             <span class="keywordflow">break</span>;
<a name="l01356"></a>01356 
<a name="l01357"></a>01357     <span class="keywordflow">if</span> (node) {
<a name="l01358"></a>01358         <span class="comment">/* Update end frames. */</span>
<a name="l01359"></a>01359         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> == -1 || node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> &lt; ef)
<a name="l01360"></a>01360             node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> = ef;
<a name="l01361"></a>01361         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a> == -1 || node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a> &gt; ef)
<a name="l01362"></a>01362             node-&gt;<a class="code" href="structps__latnode__s.html#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a> = ef;
<a name="l01363"></a>01363         <span class="comment">/* Update best link score. */</span>
<a name="l01364"></a>01364         <span class="keywordflow">if</span> (ascr <a class="code" href="hmm_8h.html#a2874ab52613ff781c96f570ec0eb0d98" title="Is one score better than another?">BETTER_THAN</a> node-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a>)
<a name="l01365"></a>01365             node-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a> = ascr;
<a name="l01366"></a>01366     }
<a name="l01367"></a>01367     <span class="keywordflow">else</span> {
<a name="l01368"></a>01368         <span class="comment">/* New node; link to head of list */</span>
<a name="l01369"></a>01369         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="l01370"></a>01370         node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> = wid;
<a name="l01371"></a>01371         node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> = sf;
<a name="l01372"></a>01372         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> = ef;
<a name="l01373"></a>01373         node-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = FALSE;
<a name="l01374"></a>01374         node-&gt;<a class="code" href="structps__latnode__s.html#a051a7eed31e29dd75151d1b34cc4eefa" title="Links into this node.">entries</a> = NULL;
<a name="l01375"></a>01375         node-&gt;<a class="code" href="structps__latnode__s.html#a5232eefbc6e800b77e7a3c8ee3f4135d" title="Links out of this node.">exits</a> = NULL;
<a name="l01376"></a>01376         node-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a> = ascr;
<a name="l01377"></a>01377 
<a name="l01378"></a>01378         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="l01379"></a>01379         dag-&gt;<a class="code" href="structps__lattice__s.html#a838bd9223e35d012419e6225b54e393d" title="List of all nodes.">nodes</a> = node;
<a name="l01380"></a>01380         ++dag-&gt;<a class="code" href="structps__lattice__s.html#ab3690a8d16e3fa8a3b0dd3aa8277b653" title="Number of nodes in this lattice.">n_nodes</a>;
<a name="l01381"></a>01381     }
<a name="l01382"></a>01382 
<a name="l01383"></a>01383     <span class="keywordflow">return</span> node;
<a name="l01384"></a>01384 }
<a name="l01385"></a>01385 
<a name="l01386"></a>01386 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01387"></a>01387 find_node(<a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag, fsg_model_t *fsg, <span class="keywordtype">int</span> sf, int32 wid)
<a name="l01388"></a>01388 {
<a name="l01389"></a>01389     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01390"></a>01390 
<a name="l01391"></a>01391     <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="l01392"></a>01392         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == sf &amp;&amp; node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> == wid)
<a name="l01393"></a>01393             <span class="keywordflow">break</span>;
<a name="l01394"></a>01394     <span class="keywordflow">return</span> node;
<a name="l01395"></a>01395 }
<a name="l01396"></a>01396 
<a name="l01397"></a>01397 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01398"></a>01398 find_start_node(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag)
<a name="l01399"></a>01399 {
<a name="l01400"></a>01400     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01401"></a>01401     glist_t start = NULL;
<a name="l01402"></a>01402     <span class="keywordtype">int</span> nstart = 0;
<a name="l01403"></a>01403 
<a name="l01404"></a>01404     <span class="comment">/* Look for all nodes starting in frame zero with some exits. */</span>
<a name="l01405"></a>01405     <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="l01406"></a>01406         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a77d358dc8c6e0f112855e8ff0629b6c8" title="Start frame.">sf</a> == 0 &amp;&amp; node-&gt;<a class="code" href="structps__latnode__s.html#a5232eefbc6e800b77e7a3c8ee3f4135d" title="Links out of this node.">exits</a>) {
<a name="l01407"></a>01407             E_INFO(<span class="stringliteral">&quot;Start node %s.%d:%d:%d\n&quot;</span>,
<a name="l01408"></a>01408                    fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>),
<a name="l01409"></a>01409                    node-&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#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>, node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>);
<a name="l01410"></a>01410             start = glist_add_ptr(start, node);
<a name="l01411"></a>01411             ++nstart;
<a name="l01412"></a>01412         }
<a name="l01413"></a>01413     }
<a name="l01414"></a>01414 
<a name="l01415"></a>01415     <span class="comment">/* If there was more than one start node candidate, then we need</span>
<a name="l01416"></a>01416 <span class="comment">     * to create an artificial start node with epsilon transitions to</span>
<a name="l01417"></a>01417 <span class="comment">     * all of them. */</span>
<a name="l01418"></a>01418     <span class="keywordflow">if</span> (nstart == 1) {
<a name="l01419"></a>01419         node = gnode_ptr(start);
<a name="l01420"></a>01420     }
<a name="l01421"></a>01421     <span class="keywordflow">else</span> {
<a name="l01422"></a>01422         gnode_t *st;
<a name="l01423"></a>01423         <span class="keywordtype">int</span> wid;
<a name="l01424"></a>01424 
<a name="l01425"></a>01425         wid = fsg_model_word_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, <span class="stringliteral">&quot;&lt;s&gt;&quot;</span>);
<a name="l01426"></a>01426         <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>-&gt;silwords)
<a name="l01427"></a>01427             bitvec_set(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>-&gt;silwords, wid);
<a name="l01428"></a>01428         node = new_node(dag, fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, 0, 0, wid, 0);
<a name="l01429"></a>01429         <span class="keywordflow">for</span> (st = start; st; st = gnode_next(st))
<a name="l01430"></a>01430             <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, node, gnode_ptr(st), 0, 0);
<a name="l01431"></a>01431     }
<a name="l01432"></a>01432     glist_free(start);
<a name="l01433"></a>01433     <span class="keywordflow">return</span> node;
<a name="l01434"></a>01434 }
<a name="l01435"></a>01435 
<a name="l01436"></a>01436 <span class="keyword">static</span> <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *
<a name="l01437"></a>01437 find_end_node(<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs, <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag)
<a name="l01438"></a>01438 {
<a name="l01439"></a>01439     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01440"></a>01440     glist_t end = NULL;
<a name="l01441"></a>01441     <span class="keywordtype">int</span> nend = 0;
<a name="l01442"></a>01442 
<a name="l01443"></a>01443     <span class="comment">/* Look for all nodes ending in last frame with some entries. */</span>
<a name="l01444"></a>01444     <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="l01445"></a>01445         <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> == dag-&gt;<a class="code" href="structps__lattice__s.html#aceffa52806f2467e4c83356fef3edc87" title="Number of frames for this utterance.">n_frames</a> - 1 &amp;&amp; node-&gt;<a class="code" href="structps__latnode__s.html#a051a7eed31e29dd75151d1b34cc4eefa" title="Links into this node.">entries</a>) {
<a name="l01446"></a>01446             E_INFO(<span class="stringliteral">&quot;End node %s.%d:%d:%d (%d)\n&quot;</span>,
<a name="l01447"></a>01447                    fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>),
<a name="l01448"></a>01448                    node-&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#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>, node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>, node-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a>);
<a name="l01449"></a>01449             end = glist_add_ptr(end, node);
<a name="l01450"></a>01450             ++nend;
<a name="l01451"></a>01451         }
<a name="l01452"></a>01452     }
<a name="l01453"></a>01453 
<a name="l01454"></a>01454     <span class="keywordflow">if</span> (nend == 1) {
<a name="l01455"></a>01455         node = gnode_ptr(end);
<a name="l01456"></a>01456     }
<a name="l01457"></a>01457     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nend == 0) {
<a name="l01458"></a>01458         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *last = NULL;
<a name="l01459"></a>01459         <span class="keywordtype">int</span> ef = 0;
<a name="l01460"></a>01460 
<a name="l01461"></a>01461         <span class="comment">/* If there were no end node candidates, then just use the</span>
<a name="l01462"></a>01462 <span class="comment">         * node with the last exit frame. */</span>
<a name="l01463"></a>01463         <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="l01464"></a>01464             <span class="keywordflow">if</span> (node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a> &gt; ef &amp;&amp; node-&gt;<a class="code" href="structps__latnode__s.html#a051a7eed31e29dd75151d1b34cc4eefa" title="Links into this node.">entries</a>) {
<a name="l01465"></a>01465                 last = node;
<a name="l01466"></a>01466                 ef = node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>;
<a name="l01467"></a>01467             }
<a name="l01468"></a>01468         }
<a name="l01469"></a>01469         node = last;
<a name="l01470"></a>01470         <span class="keywordflow">if</span> (node)
<a name="l01471"></a>01471             E_INFO(<span class="stringliteral">&quot;End node %s.%d:%d:%d (%d)\n&quot;</span>,
<a name="l01472"></a>01472                    fsg_model_word_str(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>),
<a name="l01473"></a>01473                    node-&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#a584ee5a303355d851ac903718998df14" title="First end frame.">fef</a>, node-&gt;<a class="code" href="structps__latnode__s.html#a5c7b9114d131151d6ce85228ea9f829d" title="Last end frame.">lef</a>, node-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a>);
<a name="l01474"></a>01474     }    
<a name="l01475"></a>01475     <span class="keywordflow">else</span> {
<a name="l01476"></a>01476         <span class="comment">/* If there was more than one end node candidate, then we need</span>
<a name="l01477"></a>01477 <span class="comment">         * to create an artificial end node with epsilon transitions</span>
<a name="l01478"></a>01478 <span class="comment">         * out of all of them. */</span>
<a name="l01479"></a>01479         gnode_t *st;
<a name="l01480"></a>01480         <span class="keywordtype">int</span> wid;
<a name="l01481"></a>01481 
<a name="l01482"></a>01482         wid = fsg_model_word_add(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, <span class="stringliteral">&quot;&lt;/s&gt;&quot;</span>);
<a name="l01483"></a>01483         <span class="keywordflow">if</span> (fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>-&gt;silwords)
<a name="l01484"></a>01484             bitvec_set(fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>-&gt;silwords, wid);
<a name="l01485"></a>01485         node = new_node(dag, fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>, wid, 0);
<a name="l01486"></a>01486         <span class="comment">/* Use the &quot;best&quot; (in reality it will be the only) exit link</span>
<a name="l01487"></a>01487 <span class="comment">         * score from this final node as the link score. */</span>
<a name="l01488"></a>01488         <span class="keywordflow">for</span> (st = end; st; st = gnode_next(st)) {
<a name="l01489"></a>01489             <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *src = gnode_ptr(st);
<a name="l01490"></a>01490             <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, src, node, src-&gt;info.<a class="code" href="structps__latnode__s.html#a855680c8e26809995d6a341308858984" title="Best exit score (used for final nodes only)">best_exit</a>, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l01491"></a>01491         }
<a name="l01492"></a>01492     }
<a name="l01493"></a>01493     glist_free(end);
<a name="l01494"></a>01494     <span class="keywordflow">return</span> node;
<a name="l01495"></a>01495 }
<a name="l01496"></a>01496 
<a name="l01497"></a>01497 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l01498"></a>01498 mark_reachable(<a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag, <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *end)
<a name="l01499"></a>01499 {
<a name="l01500"></a>01500     glist_t q;
<a name="l01501"></a>01501 
<a name="l01502"></a>01502     <span class="comment">/* It doesn&#39;t matter which order we do this in. */</span>
<a name="l01503"></a>01503     end-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = TRUE;
<a name="l01504"></a>01504     q = glist_add_ptr(NULL, end);
<a name="l01505"></a>01505     <span class="keywordflow">while</span> (q) {
<a name="l01506"></a>01506         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node = gnode_ptr(q);
<a name="l01507"></a>01507         <a class="code" href="structlatlink__list__s.html" title="Linked list of DAG link pointers.">latlink_list_t</a> *x;
<a name="l01508"></a>01508 
<a name="l01509"></a>01509         <span class="comment">/* Pop the front of the list. */</span>
<a name="l01510"></a>01510         q = gnode_free(q, NULL);
<a name="l01511"></a>01511         <span class="comment">/* Expand all its predecessors that haven&#39;t been seen yet. */</span>
<a name="l01512"></a>01512         <span class="keywordflow">for</span> (x = node-&gt;<a class="code" href="structps__latnode__s.html#a051a7eed31e29dd75151d1b34cc4eefa" title="Links into this node.">entries</a>; x; x = x-&gt;next) {
<a name="l01513"></a>01513             <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *next = x-&gt;link-&gt;<a class="code" href="structps__latlink__s.html#ab0912c26d1472b4c5c07042c19ffb979" title="From node.">from</a>;
<a name="l01514"></a>01514             <span class="keywordflow">if</span> (!next-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a>) {
<a name="l01515"></a>01515                 next-&gt;<a class="code" href="structps__latnode__s.html#af9c4c69f5f85bbc36818357a52432565" title="From.">reachable</a> = TRUE;
<a name="l01516"></a>01516                 q = glist_add_ptr(q, next);
<a name="l01517"></a>01517             }
<a name="l01518"></a>01518         }
<a name="l01519"></a>01519     }
<a name="l01520"></a>01520 }
<a name="l01521"></a>01521 
<a name="l01530"></a>01530 <span class="keyword">static</span> <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *
<a name="l01531"></a>01531 fsg_search_lattice(<a class="code" href="structps__search__s.html" title="Base structure for search module.">ps_search_t</a> *search)
<a name="l01532"></a>01532 {
<a name="l01533"></a>01533     <a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *fsgs;
<a name="l01534"></a>01534     fsg_model_t *fsg;
<a name="l01535"></a>01535     <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01536"></a>01536     <a class="code" href="structps__lattice__s.html" title="Word graph structure used in bestpath/nbest search.">ps_lattice_t</a> *dag;
<a name="l01537"></a>01537     int32 i, n;
<a name="l01538"></a>01538 
<a name="l01539"></a>01539     fsgs = (<a class="code" href="structfsg__search__s.html" title="Implementation of FSG search (and &amp;quot;FSG set&amp;quot;) structure.">fsg_search_t</a> *)search;
<a name="l01540"></a>01540 
<a name="l01541"></a>01541     <span class="comment">/* Check to see if a lattice has previously been created over the</span>
<a name="l01542"></a>01542 <span class="comment">     * same number of frames, and reuse it if so. */</span>
<a name="l01543"></a>01543     <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> == fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>)
<a name="l01544"></a>01544         <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="l01545"></a>01545 
<a name="l01546"></a>01546     <span class="comment">/* Nope, create a new one. */</span>
<a name="l01547"></a>01547     <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="l01548"></a>01548     search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a> = NULL;
<a name="l01549"></a>01549     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, fsgs-&gt;<a class="code" href="structfsg__search__s.html#a34bfe241a4aa42d25aef7e248a00047d" title="Current frame.">frame</a>);
<a name="l01550"></a>01550     fsg = fsgs-&gt;<a class="code" href="structfsg__search__s.html#ab1877ffe7d77ddb79bab53fb95577946" title="Currently active FSG; NULL if none.">fsg</a>;
<a name="l01551"></a>01551 
<a name="l01552"></a>01552     <span class="comment">/*</span>
<a name="l01553"></a>01553 <span class="comment">     * Each history table entry represents a link in the word graph.</span>
<a name="l01554"></a>01554 <span class="comment">     * The set of nodes is determined by the number of unique</span>
<a name="l01555"></a>01555 <span class="comment">     * (word,start-frame) pairs in the history table.  So we will</span>
<a name="l01556"></a>01556 <span class="comment">     * first find all those nodes.</span>
<a name="l01557"></a>01557 <span class="comment">     */</span>
<a name="l01558"></a>01558     n = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l01559"></a>01559     <span class="keywordflow">for</span> (i = 0; i &lt; n; ++i) {
<a name="l01560"></a>01560         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *fh = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, i);
<a name="l01561"></a>01561         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *node;
<a name="l01562"></a>01562         int32 ascr;
<a name="l01563"></a>01563         <span class="keywordtype">int</span> sf;
<a name="l01564"></a>01564 
<a name="l01565"></a>01565         <span class="comment">/* Skip null transitions. */</span>
<a name="l01566"></a>01566         <span class="keywordflow">if</span> (fh-&gt;fsglink == NULL || fh-&gt;fsglink-&gt;wid == -1)
<a name="l01567"></a>01567             <span class="keywordflow">continue</span>;
<a name="l01568"></a>01568 
<a name="l01569"></a>01569         <span class="comment">/* Find the start node of this link. */</span>
<a name="l01570"></a>01570         <span class="keywordflow">if</span> (fh-&gt;pred) {
<a name="l01571"></a>01571             <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *pfh = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, fh-&gt;pred);
<a name="l01572"></a>01572             <span class="comment">/* FIXME: We include the transition score in the lattice</span>
<a name="l01573"></a>01573 <span class="comment">             * link score.  This is because of the practical</span>
<a name="l01574"></a>01574 <span class="comment">             * difficulty of obtaining it separately in bestpath or</span>
<a name="l01575"></a>01575 <span class="comment">             * forward-backward search, and because it is essentially</span>
<a name="l01576"></a>01576 <span class="comment">             * a unigram probability, so there is no need to treat it</span>
<a name="l01577"></a>01577 <span class="comment">             * separately from the acoustic score.  However, it&#39;s not</span>
<a name="l01578"></a>01578 <span class="comment">             * clear that this will actually yield correct results.*/</span>
<a name="l01579"></a>01579             ascr = fh-&gt;score - pfh-&gt;score;
<a name="l01580"></a>01580             sf = pfh-&gt;frame + 1;
<a name="l01581"></a>01581         }
<a name="l01582"></a>01582         <span class="keywordflow">else</span> {
<a name="l01583"></a>01583             ascr = fh-&gt;score;
<a name="l01584"></a>01584             sf = 0;
<a name="l01585"></a>01585         }
<a name="l01586"></a>01586 
<a name="l01587"></a>01587         <span class="comment">/*</span>
<a name="l01588"></a>01588 <span class="comment">         * Note that although scores are tied to links rather than</span>
<a name="l01589"></a>01589 <span class="comment">         * nodes, it&#39;s possible that there are no links out of the</span>
<a name="l01590"></a>01590 <span class="comment">         * destination node, and thus we need to preserve its score in</span>
<a name="l01591"></a>01591 <span class="comment">         * case it turns out to be utterance-final.</span>
<a name="l01592"></a>01592 <span class="comment">         */</span>
<a name="l01593"></a>01593         node = new_node(dag, fsg, sf, fh-&gt;frame, fh-&gt;fsglink-&gt;wid, ascr);
<a name="l01594"></a>01594     }
<a name="l01595"></a>01595 
<a name="l01596"></a>01596     <span class="comment">/*</span>
<a name="l01597"></a>01597 <span class="comment">     * Now, we will create links only to nodes that actually exist.</span>
<a name="l01598"></a>01598 <span class="comment">     */</span>
<a name="l01599"></a>01599     n = fsg_history_n_entries(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>);
<a name="l01600"></a>01600     <span class="keywordflow">for</span> (i = 0; i &lt; n; ++i) {
<a name="l01601"></a>01601         <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *fh = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, i);
<a name="l01602"></a>01602         fsg_arciter_t *itor;
<a name="l01603"></a>01603         <a class="code" href="structps__latnode__s.html" title="DAG nodes.">ps_latnode_t</a> *src, *dest;
<a name="l01604"></a>01604         int32 ascr;
<a name="l01605"></a>01605         <span class="keywordtype">int</span> sf;
<a name="l01606"></a>01606 
<a name="l01607"></a>01607         <span class="comment">/* Skip null transitions. */</span>
<a name="l01608"></a>01608         <span class="keywordflow">if</span> (fh-&gt;fsglink == NULL || fh-&gt;fsglink-&gt;wid == -1)
<a name="l01609"></a>01609             <span class="keywordflow">continue</span>;
<a name="l01610"></a>01610 
<a name="l01611"></a>01611         <span class="comment">/* Find the start node of this link and calculate its link score. */</span>
<a name="l01612"></a>01612         <span class="keywordflow">if</span> (fh-&gt;pred) {
<a name="l01613"></a>01613             <a class="code" href="structfsg__hist__entry__s.html">fsg_hist_entry_t</a> *pfh = fsg_history_entry_get(fsgs-&gt;<a class="code" href="structfsg__search__s.html#abc949ccaab380bcf5b452d1cac54469b" title="For storing the Viterbi search history.">history</a>, fh-&gt;pred);
<a name="l01614"></a>01614             sf = pfh-&gt;frame + 1;
<a name="l01615"></a>01615             ascr = fh-&gt;score - pfh-&gt;score;
<a name="l01616"></a>01616         }
<a name="l01617"></a>01617         <span class="keywordflow">else</span> {
<a name="l01618"></a>01618             ascr = fh-&gt;score;
<a name="l01619"></a>01619             sf = 0;
<a name="l01620"></a>01620         }
<a name="l01621"></a>01621         src = find_node(dag, fsg, sf, fh-&gt;fsglink-&gt;wid);
<a name="l01622"></a>01622     
<a name="l01623"></a>01623         sf = fh-&gt;frame + 1;
<a name="l01624"></a>01624         <span class="keywordflow">for</span> (itor = fsg_model_arcs(fsg, fsg_link_to_state(fh-&gt;fsglink));
<a name="l01625"></a>01625              itor; itor = fsg_arciter_next(itor)) {
<a name="l01626"></a>01626             fsg_link_t *link = fsg_arciter_get(itor);
<a name="l01627"></a>01627 
<a name="l01628"></a>01628             <span class="comment">/* FIXME: Need to figure out what to do about tag transitions. */</span>
<a name="l01629"></a>01629             <span class="keywordflow">if</span> (link-&gt;wid &gt;= 0) {
<a name="l01630"></a>01630                 <span class="comment">/*</span>
<a name="l01631"></a>01631 <span class="comment">                 * For each non-epsilon link following this one, look for a</span>
<a name="l01632"></a>01632 <span class="comment">                 * matching node in the lattice and link to it.</span>
<a name="l01633"></a>01633 <span class="comment">                 */</span>
<a name="l01634"></a>01634                 <span class="keywordflow">if</span> ((dest = find_node(dag, fsg, sf, link-&gt;wid)) != NULL)
<a name="l01635"></a>01635                     <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, src, dest, ascr, fh-&gt;frame);
<a name="l01636"></a>01636             }
<a name="l01637"></a>01637             <span class="keywordflow">else</span> {
<a name="l01638"></a>01638                 <span class="comment">/*</span>
<a name="l01639"></a>01639 <span class="comment">                 * Transitive closure on nulls has already been done, so we</span>
<a name="l01640"></a>01640 <span class="comment">                 * just need to look one link forward from them.</span>
<a name="l01641"></a>01641 <span class="comment">                 */</span>
<a name="l01642"></a>01642                 fsg_arciter_t *itor2;
<a name="l01643"></a>01643 
<a name="l01644"></a>01644                 <span class="comment">/* Add all non-null links out of j. */</span>
<a name="l01645"></a>01645                 <span class="keywordflow">for</span> (itor2 = fsg_model_arcs(fsg, fsg_link_to_state(link));
<a name="l01646"></a>01646                      itor2; itor2 = fsg_arciter_next(itor2)) {
<a name="l01647"></a>01647                     fsg_link_t *link = fsg_arciter_get(itor2);
<a name="l01648"></a>01648                     <span class="keywordflow">if</span> (link-&gt;wid == -1)
<a name="l01649"></a>01649                         <span class="keywordflow">continue</span>;
<a name="l01650"></a>01650                     <span class="keywordflow">if</span> ((dest = find_node(dag, fsg, sf, link-&gt;wid)) != NULL)
<a name="l01651"></a>01651                         <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, src, dest, ascr, fh-&gt;frame);
<a name="l01652"></a>01652                 }
<a name="l01653"></a>01653             }
<a name="l01654"></a>01654         }
<a name="l01655"></a>01655     }
<a name="l01656"></a>01656 
<a name="l01657"></a>01657     <span class="comment">/* Figure out which nodes are the start and end nodes. */</span>
<a name="l01658"></a>01658     <span class="keywordflow">if</span> ((dag-&gt;<a class="code" href="structps__lattice__s.html#a5d936695a3813e117d20b585d48db8fe" title="Starting node.">start</a> = find_start_node(fsgs, dag)) == NULL)
<a name="l01659"></a>01659         <span class="keywordflow">goto</span> error_out;
<a name="l01660"></a>01660     <span class="keywordflow">if</span> ((dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a> = find_end_node(fsgs, dag)) == NULL)
<a name="l01661"></a>01661         <span class="keywordflow">goto</span> error_out;
<a name="l01662"></a>01662     E_INFO(<span class="stringliteral">&quot;lattice start node %s.%d end node %s.%d\n&quot;</span>,
<a name="l01663"></a>01663            fsg_model_word_str(fsg, 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="l01664"></a>01664            fsg_model_word_str(fsg, 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="l01665"></a>01665     <span class="comment">/* FIXME: Need to calculate final_node_ascr here. */</span>
<a name="l01666"></a>01666 
<a name="l01667"></a>01667     <span class="comment">/*</span>
<a name="l01668"></a>01668 <span class="comment">     * Convert word IDs from FSG to dictionary.</span>
<a name="l01669"></a>01669 <span class="comment">     */</span>
<a name="l01670"></a>01670     <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="l01671"></a>01671         node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a> = dict_wordid(dag-&gt;<a class="code" href="structps__lattice__s.html#a9ebaeb7be7a83980569f0c544eb6babb" title="Search (if generated by search).">search</a>-&gt;<a class="code" href="structps__search__s.html#a918f243fa966e72c47f697fb9e60089d" title="Pronunciation dictionary.">dict</a>,
<a name="l01672"></a>01672                                 fsg_model_word_str(fsg, node-&gt;<a class="code" href="structps__latnode__s.html#afd85dbd410d6e6d970c73088bc6fb97e" title="Dictionary word id.">wid</a>));
<a name="l01673"></a>01673         node-&gt;<a class="code" href="structps__latnode__s.html#ae3b3dc7d14347e6380859c74b9a02589" title="Dictionary base word id.">basewid</a> = dict_basewid(dag-&gt;<a class="code" href="structps__lattice__s.html#a9ebaeb7be7a83980569f0c544eb6babb" title="Search (if generated by search).">search</a>-&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="l01674"></a>01674     }
<a name="l01675"></a>01675 
<a name="l01676"></a>01676     <span class="comment">/*</span>
<a name="l01677"></a>01677 <span class="comment">     * Now we are done, because the links in the graph are uniquely</span>
<a name="l01678"></a>01678 <span class="comment">     * defined by the history table.  However we should remove any</span>
<a name="l01679"></a>01679 <span class="comment">     * nodes which are not reachable from the end node of the FSG.</span>
<a name="l01680"></a>01680 <span class="comment">     * Everything is reachable from the start node by definition.</span>
<a name="l01681"></a>01681 <span class="comment">     */</span>
<a name="l01682"></a>01682     mark_reachable(dag, dag-&gt;<a class="code" href="structps__lattice__s.html#a00f30e2689853d6bcb31c8005a69dc7b" title="Ending node.">end</a>);
<a name="l01683"></a>01683 
<a name="l01684"></a>01684     <a class="code" href="ps__lattice_8c.html#a6da4e36322aaab4d2ebe812bee9a4439" title="Remove nodes marked as unreachable.">ps_lattice_delete_unreachable</a>(dag);
<a name="l01685"></a>01685     {
<a name="l01686"></a>01686         int32 silpen, fillpen;
<a name="l01687"></a>01687 
<a name="l01688"></a>01688         silpen = (int32)(logmath_log(fsg-&gt;lmath,
<a name="l01689"></a>01689                                      cmd_ln_float32_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-silprob&quot;</span>))
<a name="l01690"></a>01690                          * fsg-&gt;lw)
<a name="l01691"></a>01691             &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l01692"></a>01692         fillpen = (int32)(logmath_log(fsg-&gt;lmath,
<a name="l01693"></a>01693                                       cmd_ln_float32_r(ps_search_config(fsgs), <span class="stringliteral">&quot;-fillprob&quot;</span>))
<a name="l01694"></a>01694                           * fsg-&gt;lw)
<a name="l01695"></a>01695             &gt;&gt; <a class="code" href="hmm_8h.html#af94da16e3e5b550b9be05b0f07402cc7" title="Shift count for senone scores.">SENSCR_SHIFT</a>;
<a name="l01696"></a>01696         <a class="code" href="ps__lattice_8c.html#a9b40adaa059978fe33959d59da1b6919" title="Bypass filler words.">ps_lattice_bypass_fillers</a>(dag, silpen, fillpen);
<a name="l01697"></a>01697     }
<a name="l01698"></a>01698     search-&gt;<a class="code" href="structps__search__s.html#a897f46c55d17e817ff1364f555b31463" title="Current hypothesis word graph.">dag</a> = dag;
<a name="l01699"></a>01699     <span class="keywordflow">return</span> dag;
<a name="l01700"></a>01700 
<a name="l01701"></a>01701 error_out:
<a name="l01702"></a>01702     <a class="code" href="ps__lattice_8h.html#a3f90e846bde47cd1acdff165b92f5c22" title="Free a lattice.">ps_lattice_free</a>(dag);
<a name="l01703"></a>01703     <span class="keywordflow">return</span> NULL;
<a name="l01704"></a>01704 
<a name="l01705"></a>01705 }
</pre></div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>
      <li class="navelem"><b>fsg_search.c</b>      </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>