1 /**
2  * @file   htk_hmm.h
3  *
4  * <EN>
5  * @brief Data structures for handling HTK %HMM definition
6  *
7  * This file defines data structures for %HMM definition file in HTK format.
8  * </EN>
9  * <JA>
10  * @brief HTK������%HMM�����ǡ�����¤�����
11  *
12  * ���Υե�����ˤ�, HTK������%HMM����ե�������ɤ߹��ि��ι�¤�Τ�
13  * �������Ƥ��ޤ���
14  * </JA>
15  *
16  * @author Akinobu LEE
17  * @date   Thu Feb 10 19:36:47 2005
18  *
19  * $Revision: 1.6 $
20  *
21  */
22 /*
23  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
24  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
25  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
26  * All rights reserved
27  */
28 
29 #ifndef __SENT_HTK_HMM_2_H__
30 #define __SENT_HTK_HMM_2_H__
31 
32 #include <sent/stddefs.h>
33 #include <sent/htk_defs.h>
34 #include <sent/ptree.h>
35 #include <sent/mfcc.h>
36 
37 /// Macro to check whether the next token is "A"
38 #define currentis(A)  (!strcasecmp(A, rdhmmdef_token))
39 /// Macro to jump to error if no token left
40 #define NoTokErr(S)      if (!rdhmmdef_token) rderr(S)
41 
42 /// Delimiter string for parsing %HMM definition file
43 #define HMMDEF_DELM " \t\n<>"
44 
45 /**
46  * @defgroup hmminfo HTK HMM definition
47  * <EN>
48  * @brief Data structures for HTK %HMM definition
49  *
50  * The data is defined in each levels from model, state to Gaussian
51  * components (mean and variance).  Each level unit almost corresponds
52  * to the macro
53  * definition in the HTK definition language.  Each data has links to
54  * data of lower level, and also has a linked list to the data in the
55  * same level.
56  * </EN>
57  * <JA>
58  * @brief HTK��%HMM���Ǽ���뤿��Υǡ�����¤���
59  *
60  * �ǡ�����¤�ϥ�ǥ롦���֤��饬����ʬ�ۤ�ʿ�ѡ�ʬ���ޤdzƥ�٥뤴�Ȥ�
61  * �������Ƥ��ޤ����ƥ�٥�Ϥ����褽 HTK �Υޥ���������б����Ƥ��ޤ���
62  * �ƥǡ�����, ���̤Υǡ�����¤�ؤΥݥ���
63  * �����Ʊ��٥�ι�¤��Ʊ�ΤΥ���ꥹ�Ȥ��ݻ����Ƥ��ޤ���
64  * </JA>
65  *
66  */
67 //@{
68 /// @ingroup hmminfo
69 
70 /// Possible maximum value of state ID (in unsigned short)
71 #define MAX_STATE_NUM 2147483647
72 
73 /// Delimiter strings/characters to generate logical triphone names
74 #define HMM_RC_DLIM "+"		///< Right context delimiter in string
75 #define HMM_LC_DLIM "-"		///< Left context delimiter in string
76 #define HMM_RC_DLIM_C '+'	///< Right context delimiter in character
77 #define HMM_LC_DLIM_C '-'	///< Left context delimiter in character
78 
79 /// Default logical name of short pause model
80 #define SPMODEL_NAME_DEFAULT "sp"
81 
82 /// Length limit of HMM name (including ones generated in Julius)
83 #define MAX_HMMNAME_LEN 256
84 
85 /// Specify method of calculating approximated acoustic score at inter-word context pseudo phones on word edge
86 enum iwcd_type {
87   IWCD_UNDEF,			///< not specified explicitly
88   IWCD_MAX,			///< Use maximum score among context variants
89   IWCD_AVG,			///< Use average score among context variants
90   IWCD_NBEST			///< Use average of N-best scores among context variants
91 };
92 
93 /* options info */
94 
95 /// Stream information (although current Julius supports only single stream)
96 typedef struct {
97   short num;			///< Number of stream
98   short vsize[MAXSTREAMNUM];	///< Vector size for each stream
99 } HTK_HMM_StreamInfo;
100 
101 /// %HMM Option
102 typedef struct {
103   HTK_HMM_StreamInfo stream_info; ///< Stream information of this %HMM
104   short vec_size;		///< Size of parameter vector in number of dimension
105   short cov_type;		///< Type of covariance matrix , see also htk_defs.h
106   short dur_type;		///< Type of duration , see also htk_defs.h
107   short param_type;		///< Type of parameter , see also htk_defs.h
108 } HTK_HMM_Options;
109 
110 /// %HMM transition table
111 typedef struct _HTK_HMM_trans {
112   char *name;			///< Name (NULL if not defined as Macro)
113   short statenum;		///< Number of state
114   PROB **a;			///< Matrix of transition probabilities
115   struct _HTK_HMM_trans *next;  ///< Pointer to next data, NULL if last
116 } HTK_HMM_Trans;
117 
118 /// %HMM variance data
119 typedef struct _HTK_HMM_variance {
120   char *name;			///< Name (NULL if not defined as Macro)
121   VECT *vec;			///< Covariance vector (diagonal)
122   short len;			///< Length of above
123   struct _HTK_HMM_variance *next; ///< Pointer to next data, NULL if last
124 } HTK_HMM_Var;
125 
126 /// %HMM Gaussian density (or mixture) data
127 typedef struct _HTK_HMM_dens {
128   char *name;			///< Name (NULL if not defined as Macro)
129   VECT *mean;			///< Mean vector
130   short meanlen;		///< Length of above
131   HTK_HMM_Var *var;		///< Link to assigned variance vector
132   /**
133    * Constant value in log scale for calculating Gaussiann output probability.
134    * @sa libsent/sec/hmminfo/rdhmmdef_dens.c
135    */
136   LOGPROB gconst;
137   struct _HTK_HMM_dens *next;	///< Pointer to next data, NULL if last
138 } HTK_HMM_Dens;
139 
140 /// %HMM stream weight definition
141 typedef struct _HTK_HMM_stream_weight {
142   char *name;			///< Name (NULL for in-line definition)
143   VECT *weight;			///< Weight of each stream in log scale
144   short len;			///< Length of above
145   struct _HTK_HMM_stream_weight *next; ///< Pointer to next data, NULL on last
146 } HTK_HMM_StreamWeight;
147 
148 /**
149  * @brief %HMM mixture PDF for a stream
150  *
151  * @note
152  * In a tied-mixture model, @a b points to a codebook defined as GCODEBOOK
153  * intead of the array of densities.
154  *
155  */
156 typedef struct _HTK_HMM_PDF {
157   char *name;			///< Name (NULL for in-line definition)
158   boolean tmix;			///< TRUE if this is assigned to tied-mixture codebook
159   short stream_id;		///< Stream ID to which this pdf is assigned, begins from 0
160   short mix_num;		///< Number of densities (mixtures) assigned.
161   HTK_HMM_Dens **b;		///< Link array to assigned densities, or pointer to GCODEBOOK in tied-mixture model
162   PROB *bweight;		///< Weights corresponding to above
163   struct _HTK_HMM_PDF *next;	///< Pointer to next data, or NULL at last
164 } HTK_HMM_PDF;
165 
166 /**
167  * @brief %HMM state data
168  *
169  */
170 typedef struct _HTK_HMM_state {
171   char *name;			///< Name (NULL if not defined as Macro)
172   short nstream;		///< Num of stream
173   HTK_HMM_StreamWeight *w;	///< Pointer to stream weight data, or NULL is not specified
174   HTK_HMM_PDF **pdf;	        ///< Array of mixture PDFs for each stream
175   int id; 			///< Uniq state id starting from 0 for caching of output probability
176   struct _HTK_HMM_state *next;  ///< Pointer to next data, NULL if last
177 } HTK_HMM_State;
178 
179 /// Top %HMM model, corresponds to "~h" macro in hmmdefs
180 typedef struct _HTK_HMM_data {
181   char *name;			///< Name (NULL if not defined as Macro)
182   short state_num;		///< Number of states in this model
183   HTK_HMM_State **s;		///< Array of states in this model
184   HTK_HMM_Trans *tr;		///< Link to assigned transition matrix
185   struct _HTK_HMM_data *next;   ///< Pointer to next data, NULL if last
186 } HTK_HMM_Data;
187 
188 /// Gaussian mixture codebook in tied-mixture model
189 typedef struct {
190   char *name;			///< Codebook name (NULL if not defined as Macro)
191   int num;			///< Number of mixtures in this codebook
192   HTK_HMM_Dens **d;		///< Array of links to mixture instances
193   unsigned short id;            ///< Uniq id for caching of output probability
194 } GCODEBOOK;
195 //@}
196 
197 /// Set of %HMM states for Gaussian Mixture Selection
198 typedef struct {
199   HTK_HMM_State *state;		///< Pointer to %HMM states defined for GMS
200   /* GCODEBOOK *book;*/		/* pointer to the corresponding codebook in hmminfo */
201 } GS_SET;
202 
203 /**
204  * @defgroup cdset Context-Dependent HMM set
205  * <EN>
206  * @brief Set of %HMM states with the same base phone and state location
207  *
208  * This structure will be used to handle cross-word triphone on the 1st pass.
209  * At a triphone %HMM at the edge of a word in the tree lexicon,
210  * the state nodes should have a set of %HMM states with the same base phone of
211  * all triphones at the same location instead of a single state information.
212  * This context-dependent %HMM set for cross-word triphone is also
213  * called as "pseudo" phone in Julius.
214  *
215  * When computing the 1st pass, the maximum (or average or N-best average)
216  * value from the likelihoods of state set will be taken as the output
217  * probability of the states instead of the actual cross-word triphone.
218  *
219  *
220  * This approximated value will be fixed by re-computation on the 2nd pass.
221  * </EN>
222  * <JA>
223  * @brief Ʊ���١������Ǥ�Ʊ�����֤ˤ���%HMM���֤ν���
224  *
225  * ���ι�¤�Τ��裱�ѥ���ñ��֥ȥ饤�ե�������Τ��Ѥ����ޤ���
226  * �ڹ�¤�������ǡ�ñ�����ü�Υȥ饤�ե���%HMM�ˤ�����ƾ��֤ϡ�
227  * �̾��%HMM�Ȥϰۤʤꤽ�ν�ü���Ǥ�Ʊ���١������Ǥ���ĥȥ饤�ե����
228  * Ʊ�����֤ξ��֤Υꥹ�Ȥ�����ޤ������Υꥹ�Ȳ����줿����ƥ����Ȱ�¸
229  * %HMM�ν���ϡ�"pseudo" phone �Ȥ�ƤФ�ޤ���
230  *
231  * �裱�ѥ��׻����ˤϡ����ξ��֤β������٤ϡ�����ñ��֥ȥ饤�ե����
232  * ����ͤȤ��ơ��ꥹ����γƾ��֤β������٤κ����͡ʤ��뤤��ʿ���͡�
233  * ���뤤��Nbest�ξ��֤�ʿ���͡ˤ��Ѥ����롥
234  *
235  * ���ζ���ͤ��裲�ѥ��ǺƷ׻�����롥
236  * </JA>
237  *
238  * @sa htk_hmm.h
239  * @sa libsent/src/hmminfo/cdhmm.c
240  * @sa libsent/src/hmminfo/cdset.c
241  * @sa libsent/src/hmminfo/guess_cdHMM.c
242  *
243  */
244 //@{
245 /// @ingroup cdset
246 
247 /// Context-dependent state set, equivalent to HTK_HMM_State, part of pseudo phone
248 typedef struct {
249   HTK_HMM_State **s;		///< Link Array to belonging states
250   unsigned short num;		///< Number of states
251   unsigned short maxnum;	///< Allocated number of above
252 } CD_State_Set;
253 /**
254  * @brief Context-dependent %HMM set (called "pseudo") for a logical context
255  *
256  * Context-dependent %HMM set for a logical context
257  * (e.g. "a-k", "e+b", "e", each corresponds to triphone list of
258  * "a-k+*", "*-e+b", "*-e+*").
259  */
260 typedef struct _cd_set{
261   char *name;			///< Logical name of this %HMM set ("a-k", "e+b", "e", etc.)
262   CD_State_Set *stateset;	///< Array of state set for each state location
263   unsigned short state_num;	///< Number of state set
264   HTK_HMM_Trans *tr;		///< Transition matrix
265   struct _cd_set *next;         ///< Pointer to next data, NULL if last
266 } CD_Set;
267 /// Top structure to hold all the %HMM sets
268 typedef struct {
269   APATNODE *cdtree;		///< Root of index tree for name lookup
270 } HMM_CDSET_INFO;
271 //@}
272 
273 /**
274  * @ingroup cdset
275  *
276  * @brief Logical %HMM to map logical names to physical/pseudo %HMM
277  *
278  * This data maps logical %HMM name to physical (defined) %HMM or pseudo %HMM.
279  * The logical %HMM names are basically loaded from %HMMList mapping file.
280  * Biphone/monophone %HMM names, not listed in the %HMMList file,
281  * are mapped to pseudo phones, which represents the context-dependent %HMM
282  * set.
283  *
284  * For example, if logical biphone %HMM name "e-k" is defined in %HMM definition
285  * file or its mapping is specified in the HMMList file, the Logical %HMM name
286  * "e-k" will be mapped to the corresponding defined %HMM.
287  * If "e-k" does not exist in
288  * both %HMM definition file and HMMList file, triphones whose name matches
289  * "e-k+*" will be gathered to phone context-dependent %HMM set "e-k", and
290  * the logical %HMM name "e-k" will be mapped to this %HMM set.
291  *
292  * The context-dependent %HMM is also called a "pseudo" phone in Julius.
293  *
294  */
295 typedef struct _HMM_logical {
296   char *name;			///< Name string of this logical %HMM
297   boolean is_pseudo;		///< TRUE if this is mapped to pseudo %HMM
298   /// Actual body of state definition
299   union {
300     HTK_HMM_Data *defined;	///< pointer to the mapped physical %HMM
301     CD_Set *pseudo;		///< pointer to the mapped pseudo %HMM
302   } body;
303   struct _HMM_logical *next;   ///< Pointer to next data, NULL if last
304 } HMM_Logical;
305 
306 /**
307  * @ingroup hmminfo
308  *
309  * @brief Basephone information extracted from hmminfo
310  */
311 typedef struct {
312   char *name;			///< Base phone name
313   boolean bgnflag;		///< TRUE if it can appear on word beginning determined by word dictionary
314   boolean endflag;		///< TRUE if it can appear on word end determined by word dictionary
315 } BASEPHONE;
316 /**
317  * @ingroup hmminfo
318  *
319  * @brief List of all basephone in hmminfo
320  */
321 typedef struct {
322   int num;			///< Total number of base phone
323   int bgnnum;			///< Number of phones that can appear on word beginning
324   int endnum;			///< Number of phones that can appear on word end
325   APATNODE *root;		///< Root of index tree for name lookup
326 } HMM_basephone;
327 
328 /**
329  * @ingroup hmminfo
330  *
331  * @brief Top %HMM structure that holds all the HTK %HMM definition
332  */
333 typedef struct {
334   /**
335    * @name %HMM definitions from hmmdefs
336    */
337   //@{
338   HTK_HMM_Options opt;		///< Global option
339   HTK_HMM_Trans *trstart;	///< Root pointer to the list of transition matrixes
340   HTK_HMM_Var *vrstart;		///< Root pointer to the list of variance data
341   HTK_HMM_Dens *dnstart;	///< Root pointer to the list of density (mixture) data
342   HTK_HMM_PDF *pdfstart;	///< Root pointer to the list of mixture pdf data
343   HTK_HMM_StreamWeight *swstart; ///< Root pointer to the list of stream weight data
344   HTK_HMM_State *ststart;	///< Root pointer to the list of state data
345   HTK_HMM_Data *start;		///< Root pointer to the list of models
346   //@}
347 
348   /**
349    * @name logical %HMM
350    */
351   //@{
352   HMM_Logical *lgstart;		///< Root pointer to the list of Logical %HMMs
353   //@}
354 
355   /**
356    * @name Root nodes of index tree for name lookup of %HMM instances
357    */
358   //@{
359   APATNODE *tr_root;		///< Root index node for transition matrixes
360   APATNODE *vr_root;		///< Root index node for variance data
361   APATNODE *sw_root;		///< Root index node for stream weight data
362   APATNODE *dn_root;		///< Root index node for density data
363   APATNODE *pdf_root;		///< Root index node for mixture PDF
364   APATNODE *st_root;		///< Root index node for state data
365   APATNODE *physical_root;	///< Root index node for defined %HMM name
366   APATNODE *logical_root;	///< Root index node for logical %HMM name
367   APATNODE *codebook_root;	///< Root index node for Gaussian codebook of tied mixture %HMM
368   //@}
369 
370   /**
371    * @name Information extracted from %HMM instances
372    */
373   //@{
374   HMM_basephone basephone;	///< Base phone names extracted from logical %HMM
375   HMM_CDSET_INFO cdset_info;	///< Context-dependent pseudo phone set
376   //@}
377 
378   /**
379    * @name Misc. model information
380    */
381   //@{
382   boolean need_multipath; ///< TRUE if this model needs multipath handling
383   boolean multipath;		///< TRUE if this model is treated in multipath mode
384   boolean is_triphone;		///< TRUE if this is triphone model
385   boolean is_tied_mixture;	///< TRUE if this is tied-mixture model
386   short cdset_method;		///< Selected method of computing pseudo phones in iwcd_type
387   short cdmax_num;		///< Number of N-best states when IWCD_NBEST
388   HMM_Logical *sp;		///< Link to short pause model
389   LOGPROB iwsp_penalty;		///< Extra ransition penalty for interword skippable short pause insertion for multi-path mode
390   boolean variance_inversed;	///< TRUE if variances are inversed
391 
392   int totalmixnum;		///< Total number of defined mixtures
393   int totalstatenum;		///< Total number of states
394   int totalhmmnum;		///< Total number of physical %HMM
395   int totallogicalnum;		///< Total number of logical %HMM
396   int totalpseudonum;		///< Total number of pseudo %HMM
397   int totalpdfnum;		///< Total number of mixture PDF
398   int codebooknum;		///< Total number of codebook on tied-mixture model
399   int maxcodebooksize;		///< Maximum size of codebook on tied-mixture model
400   int maxmixturenum;		///< Maximum number of Gaussian per mixture
401   int maxstatenum;		///< Maximum number of state per model
402 
403   BMALLOC_BASE *mroot;		///< Pointer for block memory allocation
404   BMALLOC_BASE *lroot;		///< Pointer for block memory allocation for logical HMM
405   BMALLOC_BASE *cdset_root;		///< Pointer for block memory allocation for logical HMM
406 
407   int *tmp_mixnum;		///< Work area for state reading
408 
409 #ifdef ENABLE_MSD
410   boolean has_msd;		///< TRUE if this model contains MSD part
411 #endif
412 
413   //@}
414 } HTK_HMM_INFO;
415 
416 /* init_phmm.c */
417 void htk_hmm_set_pause_model(HTK_HMM_INFO *hmminfo, char *spmodel_name);
418 /* rdhmmdef.c */
419 void rderr(char *str);
420 char *read_token(FILE *fp);
421 boolean rdhmmdef(FILE *, HTK_HMM_INFO *);
422 void htk_hmm_inverse_variances(HTK_HMM_INFO *hmm);
423 #ifdef ENABLE_MSD
424 void htk_hmm_check_msd(HTK_HMM_INFO *hmm);
425 #endif
426 /* rdhmmdef_options.c */
427 boolean set_global_opt(FILE *fp, HTK_HMM_INFO *hmm);
428 char *get_cov_str(short covtype);
429 char *get_dur_str(short durtype);
430 /* rdhmmdef_trans.c */
431 void trans_add(HTK_HMM_INFO *hmm, HTK_HMM_Trans *newParam);
432 HTK_HMM_Trans *get_trans_data(FILE *, HTK_HMM_INFO *);
433 void def_trans_macro(char *, FILE *, HTK_HMM_INFO *);
434 /* rdhmmdef_state.c */
435 HTK_HMM_State *get_state_data(FILE *, HTK_HMM_INFO *);
436 void def_state_macro(char *, FILE *, HTK_HMM_INFO *);
437 HTK_HMM_State *state_lookup(HTK_HMM_INFO *hmm, char *keyname);
438 void state_add(HTK_HMM_INFO *hmm, HTK_HMM_State *newParam);
439 /* rdhmmdef_mpdf.c */
440 void mpdf_add(HTK_HMM_INFO *hmm, HTK_HMM_PDF *newParam);
441 HTK_HMM_PDF *mpdf_lookup(HTK_HMM_INFO *hmm, char *keyname);
442 HTK_HMM_PDF *get_mpdf_data(FILE *fp, HTK_HMM_INFO *hmm, int mix_num, short stream_id);
443 void def_mpdf_macro(char *name, FILE *fp, HTK_HMM_INFO *hmm);
444 /* rdhmmdef_dens.c */
445 HTK_HMM_Dens *get_dens_data(FILE *, HTK_HMM_INFO *);
446 void def_dens_macro(char *, FILE *, HTK_HMM_INFO *);
447 HTK_HMM_Dens *dens_lookup(HTK_HMM_INFO *hmm, char *keyname);
448 void dens_add(HTK_HMM_INFO *hmm, HTK_HMM_Dens *newParam);
449 /* rdhmmdef_var.c */
450 HTK_HMM_Var *get_var_data(FILE *, HTK_HMM_INFO *);
451 void def_var_macro(char *, FILE *, HTK_HMM_INFO *);
452 void var_add(HTK_HMM_INFO *hmm, HTK_HMM_Var *newParam);
453 /* rdhmmdef_streamweight.c */
454 HTK_HMM_StreamWeight *get_streamweight_data(FILE *fp, HTK_HMM_INFO *hmm);
455 void def_streamweight_macro(char *, FILE *, HTK_HMM_INFO *);
456 void sw_add(HTK_HMM_INFO *hmm, HTK_HMM_StreamWeight *newParam);
457 /* rdhmmdef_data.c */
458 void def_HMM(char *, FILE *, HTK_HMM_INFO *);
459 HTK_HMM_Data *htk_hmmdata_new(HTK_HMM_INFO *);
460 void htk_hmmdata_add(HTK_HMM_INFO *hmm, HTK_HMM_Data *newParam);
461 /* rdhmmdef_tiedmix.c */
462 void tmix_read(FILE *fp, HTK_HMM_PDF *mpdf, HTK_HMM_INFO *hmm);
463 void codebook_add(HTK_HMM_INFO *hmm, GCODEBOOK *newParam);
464 /* rdhmmdef_regtree.c */
465 void def_regtree_macro(char *name, FILE *fp, HTK_HMM_INFO *hmm);
466 /* rdhmmdef_hmmlist.c */
467 boolean rdhmmlist(FILE *fp, HTK_HMM_INFO *hmminfo);
468 boolean save_hmmlist_bin(FILE *fp, HTK_HMM_INFO *hmminfo);
469 boolean load_hmmlist_bin(FILE *fp, HTK_HMM_INFO *hmminfo);
470 
471 /* put_htkdata_info.c */
472 void put_htk_trans(FILE *fp, HTK_HMM_Trans *t);
473 void put_htk_var(FILE *fp, HTK_HMM_Var *v);
474 void put_htk_dens(FILE *fp, HTK_HMM_Dens *d);
475 void put_htk_mpdf(FILE *fp, HTK_HMM_PDF *m);
476 void put_htk_state(FILE *fp, HTK_HMM_State *s);
477 void put_htk_hmm(FILE *fp, HTK_HMM_Data *h);
478 void put_logical_hmm(FILE *fp, HMM_Logical *l);
479 void print_hmmdef_info(FILE *fp, HTK_HMM_INFO *);
480 
481 HTK_HMM_INFO *hmminfo_new();
482 boolean hmminfo_free(HTK_HMM_INFO *);
483 boolean init_hmminfo(HTK_HMM_INFO *hmminfo, char *filename, char *mapfile, Value *para);
484 HTK_HMM_Data *htk_hmmdata_lookup_physical(HTK_HMM_INFO *, char *);
485 HMM_Logical *htk_hmmdata_lookup_logical(HTK_HMM_INFO *, char *);
486 void hmm_add_physical_to_logical(HTK_HMM_INFO *);
487 void hmm_add_pseudo_phones(HTK_HMM_INFO *hmminfo);
488 /* chkhmmlist.c */
489 void make_hmm_basephone_list(HTK_HMM_INFO *hmminfo);
490 
491 /* HMM type check functions */
492 boolean htk_hmm_has_several_arc_on_edge(HTK_HMM_INFO *hmminfo);
493 boolean check_hmm_limit(HTK_HMM_Data *dt);
494 boolean check_all_hmm_limit(HTK_HMM_INFO *hmm);
495 boolean check_hmm_options(HTK_HMM_INFO *hmm);
496 boolean is_skippable_model(HTK_HMM_Data *d);
497 
498 /* CCD related */
499 boolean guess_if_cd_hmm(HTK_HMM_INFO *hmm);
500 HMM_Logical *get_right_context_HMM(HMM_Logical *base, char *rc_name, HTK_HMM_INFO *hmminfo);
501 HMM_Logical *get_left_context_HMM(HMM_Logical *base, char *lc_name, HTK_HMM_INFO *hmminfo);
502 void add_right_context(char name[], char *rc);
503 void add_left_context(char name[], char *lc);
504 char *center_name(char *hmmname, char *buf);
505 char *leftcenter_name(char *hmmname, char *buf);
506 char *rightcenter_name(char *hmmname, char *buf);
507 
508 /* CD_SET related */
509 boolean regist_cdset(APATNODE **root, HTK_HMM_Data *d, char *cdname, BMALLOC_BASE **mroot);
510 boolean make_cdset(HTK_HMM_INFO *hmminfo);
511 void put_all_cdinfo(HTK_HMM_INFO *hmminfo);
512 void free_cdset(APATNODE **root, BMALLOC_BASE **mroot);
513 CD_Set *cdset_lookup(HTK_HMM_INFO *hmminfo, char *cdstr);
514 CD_Set *lcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname);
515 CD_Set *rcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname);
516 int hmm_logical_state_num(HMM_Logical *lg);
517 HTK_HMM_Trans *hmm_logical_trans(HMM_Logical *lg);
518 
519 #include <sent/htk_param.h>
520 boolean check_param_coherence(HTK_HMM_INFO *hmm, HTK_Param *pinfo);
521 boolean check_param_basetype(HTK_HMM_INFO *hmm, HTK_Param *pinfo);
522 int param_check_and_adjust(HTK_HMM_INFO *hmm, HTK_Param *pinfo, boolean vflag);
523 
524 
525 /* binary format */
526 boolean write_binhmm(FILE *fp, HTK_HMM_INFO *hmm, Value *para);
527 boolean read_binhmm(FILE *fp, HTK_HMM_INFO *hmm, boolean gzfile_p, Value *para);
528 
529 #endif /* __SENT_HTK_HMM_2_H__ */
530