libsent/src/hmminfo/rdhmmdef.c

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

Generated on Tue Dec 26 16:16:33 2006 for Julius by  doxygen 1.5.0