00001 
00035 
00036 
00037 
00038 
00039 
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 
00053 
00059 void
00060 rderr(char *str)
00061 {
00062   if (rdhmmdef_token == NULL) { 
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     
00081     if ((rdhmmdef_token = mystrtok_quote(NULL, HMMDEF_DELM)) != NULL) {
00082       
00083       return rdhmmdef_token;
00084     }
00085   } else {
00086     
00087     buf = (char *)mymalloc(MAXBUFLEN);
00088     line = 1;
00089   }
00090   
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   
00159   hmm->variance_inversed = FALSE;
00160 
00161   
00162   read_token(fp);
00163   
00164   
00165   while (rdhmmdef_token != NULL) {
00166     if (rdhmmdef_token[0] != '~') { 
00167       return FALSE;
00168     }
00169     macrosw = rdhmmdef_token[1];
00170     read_token(fp);             
00171     switch(macrosw) {
00172     case 'o':                   
00173       set_global_opt(fp,hmm);
00174       break;
00175     case 't':                   
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':                   
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':                   
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':                   
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':                   
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':                   
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   
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   
00223   conv_log_arc(hmm);
00224 
00225   
00226   if (! hmm->variance_inversed) {
00227     htk_hmm_inverse_variances(hmm);
00228     hmm->variance_inversed = TRUE;
00229   }
00230   
00231   
00232   if (!check_hmm_options(hmm)) {
00233     j_error("hmm options check failed\n");
00234   }
00235 
00236   
00237   
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   
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   
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   
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);                 
00286 }