libsent/src/hmminfo/rdhmmdef.c

Go to the documentation of this file.
00001 
00036 /*
00037  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00038  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00039  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00040  * All rights reserved
00041  */
00042 
00043 #include <sent/stddefs.h>
00044 #include <sent/htk_param.h>
00045 #include <sent/htk_hmm.h>
00046 
00047 #define MAXBUFLEN  4096         
00048 
00049 char *rdhmmdef_token;           
00050 static char *buf = NULL;        
00051 static int line;                
00052 
00053 /* global functions for rdhmmdef_*.c */
00054 
00060 void
00061 rderr(char *str)
00062 {
00063   if (rdhmmdef_token == NULL) { /* end of file */
00064     jlog("Error: rdhmmdef: %s on end of file\n", str);
00065   } else {
00066     jlog("Error: rdhmmdef: read error at line %d: %s\n", line, (str) ? str : "parse error");
00067   }
00068   jlog_flush();
00069   exit(1);
00070 }
00071 
00079 char *
00080 read_token(FILE *fp)
00081 {
00082   if (buf != NULL) {
00083     /* already have buffer */
00084     if ((rdhmmdef_token = mystrtok_quote(NULL, HMMDEF_DELM)) != NULL) {
00085       /* return next token */
00086       return rdhmmdef_token;
00087     }
00088   } else {
00089     /* init: allocate buffer for the first time */
00090     buf = (char *)mymalloc(MAXBUFLEN);
00091     line = 1;
00092   }
00093   /* read new 1 line */
00094   if (getl(buf, MAXBUFLEN, fp) == NULL) {
00095     rdhmmdef_token = NULL;
00096   } else {
00097     rdhmmdef_token = mystrtok_quote(buf, HMMDEF_DELM);
00098     line++;
00099   }
00100   return rdhmmdef_token;
00101 }
00102 
00108 static void
00109 conv_log_arc(HTK_HMM_INFO *hmm)
00110 {
00111   HTK_HMM_Trans *tr;
00112   int i,j;
00113   LOGPROB l;
00114 
00115   for (tr = hmm->trstart; tr; tr = tr->next) {
00116     for(i=0;i<tr->statenum;i++) {
00117       for(j=0;j<tr->statenum;j++) {
00118         l = tr->a[i][j];
00119         tr->a[i][j] = (l != 0.0) ? (float)log10(l) : LOG_ZERO;
00120       }
00121     }
00122   }
00123 }
00129 void
00130 htk_hmm_inverse_variances(HTK_HMM_INFO *hmm)
00131 {
00132   HTK_HMM_Var *v;
00133   int i;
00134 
00135   for (v = hmm->vrstart; v; v = v->next) {
00136     for(i=0;i<v->len;i++) {
00137       v->vec[i] = 1 / v->vec[i];
00138     }
00139   }
00140 }
00141 
00142 
00154 boolean
00155 rdhmmdef(FILE *fp, HTK_HMM_INFO *hmm)
00156 {
00157   char macrosw;
00158   char *name;
00159 
00160   /* variances in htkdefs are not inversed yet */
00161   hmm->variance_inversed = FALSE;
00162 
00163   /* read the first token */
00164   read_token(fp);
00165   
00166   /* the toplevel loop */
00167   while (rdhmmdef_token != NULL) {/* break on EOF */
00168     if (rdhmmdef_token[0] != '~') { /* toplevel commands are always macro */
00169       return FALSE;
00170     }
00171     macrosw = rdhmmdef_token[1];
00172     read_token(fp);             /* read next token after the "~.."  */
00173     switch(macrosw) {
00174     case 'o':                   /* global option */
00175       set_global_opt(fp,hmm);
00176       break;
00177     case 't':                   /* transition macro */
00178       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00179       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00180       read_token(fp);
00181       def_trans_macro(name, fp, hmm);
00182       break;
00183     case 's':                   /* state macro */
00184       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00185       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00186       read_token(fp);
00187       def_state_macro(name, fp, hmm);
00188       break;
00189     case 'm':                   /* density (mixture) macro */
00190       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00191       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00192       read_token(fp);
00193       def_dens_macro(name, fp, hmm);
00194       break;
00195     case 'h':                   /* HMM define */
00196       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00197       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00198       read_token(fp);
00199       def_HMM(name, fp, hmm);
00200       break;
00201     case 'v':                   /* Variance macro */
00202       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00203       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00204       read_token(fp);
00205       def_var_macro(name, fp, hmm);
00206       break;
00207     case 'r':                   /* Regression class macro (ignore) */
00208       name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00209       if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00210       read_token(fp);
00211       def_regtree_macro(name, fp, hmm);
00212       break;
00213     }
00214   }
00215 
00216   /* convert transition prob to log scale */
00217   conv_log_arc(hmm);
00218 
00219   jlog("Stat: rdhmmdef: ascii format HMM definition\n");
00220   
00221   /* check limitation */
00222   if (check_all_hmm_limit(hmm)) {
00223     jlog("Stat: rdhmmdef: limit check passed\n");
00224   } else {
00225     jlog("Error: rdhmmdef: cannot handle this HMM due to system limitation\n");
00226     return FALSE;
00227   }
00228 
00229   /* determine whether this model needs multi-path handling */
00230   hmm->need_multipath = htk_hmm_has_several_arc_on_edge(hmm);
00231   if (hmm->need_multipath) {
00232     jlog("Stat: rdhmmdef: this HMM requires multipath handling at decoding\n");
00233   } else {
00234     jlog("Stat: rdhmmdef: this HMM does not need multipath handling\n");
00235   }
00236   
00237   /* inverse all variance values for faster computation */
00238   if (! hmm->variance_inversed) {
00239     htk_hmm_inverse_variances(hmm);
00240     hmm->variance_inversed = TRUE;
00241   }
00242 
00243   /* check HMM parameter option type */
00244   if (!check_hmm_options(hmm)) {
00245     jlog("Error: rdhmmdef: hmm options check failed\n");
00246     return FALSE;
00247   }
00248 
00249   /* add ID number for all HTK_HMM_State */
00250   /* also calculate the maximum number of mixture */
00251   {
00252     HTK_HMM_State *stmp;
00253     int n, max;
00254     n = 0;
00255     max = 0;
00256     for (stmp = hmm->ststart; stmp; stmp = stmp->next) {
00257       if (max < stmp->mix_num) max = stmp->mix_num;
00258       stmp->id = n++;
00259       if (n >= MAX_STATE_NUM) {
00260         jlog("Error: rdhmmdef: too much states in a model > %d\n", MAX_STATE_NUM);
00261         jlog("Error: you can try changing value of MAX_STATE_NUM\n");
00262         return FALSE;
00263       }
00264     }
00265     hmm->totalstatenum = n;
00266     hmm->maxmixturenum = max;
00267   }
00268   /* compute total number of HMM models and maximum length */
00269   {
00270     HTK_HMM_Data *dtmp;
00271     int n, maxlen;
00272     n = 0;
00273     maxlen = 0;
00274     for (dtmp = hmm->start; dtmp; dtmp = dtmp->next) {
00275       if (maxlen < dtmp->state_num) maxlen = dtmp->state_num;
00276       n++;
00277     }
00278     hmm->maxstatenum = maxlen;
00279     hmm->totalhmmnum = n;
00280   }
00281   /* compute total number of mixtures */
00282   {
00283     HTK_HMM_Dens *dtmp;
00284     int n = 0;
00285     for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) {
00286       n++;
00287     }
00288     hmm->totalmixnum = n;
00289   }
00290   /* check of HMM name length exceed the maximum */
00291   {
00292     HTK_HMM_Dens *dtmp;
00293     int n = 0;
00294     for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) {
00295       n++;
00296     }
00297     hmm->totalmixnum = n;
00298   }
00299 
00300   return(TRUE);                 /* success */
00301 }

Generated on Tue Dec 18 15:59:55 2007 for Julius by  doxygen 1.5.4