00001 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #include <sent/stddefs.h>
00026 #include <sent/htk_hmm.h>
00027 
00028 extern char *rdhmmdef_token;    
00029 
00038 static GCODEBOOK *
00039 codebook_lookup(HTK_HMM_INFO *hmm, char *keyname)
00040 {
00041   GCODEBOOK *book;
00042 
00043   if (hmm->codebook_root == NULL) return(NULL);
00044   book = aptree_search_data(keyname, hmm->codebook_root);
00045   if (book != NULL && strmatch(book->name, keyname)) {
00046     return book;
00047   } else {
00048     return NULL;
00049   }
00050 }
00051 
00058 void
00059 codebook_add(HTK_HMM_INFO *hmm, GCODEBOOK *new)
00060 {
00061   GCODEBOOK *match;
00062   if (hmm->codebook_root == NULL) {
00063     hmm->codebook_root = aptree_make_root_node(new);
00064   } else {
00065     match = aptree_search_data(new->name, hmm->codebook_root);
00066     if (match != NULL && strmatch(match->name, new->name)) {
00067       jlog("Error: rdhmmdef_tiedmix: ~s \"%s\" is already defined\n", new->name);
00068       rderr(NULL);
00069     } else {
00070       aptree_add_entry(new->name, new, match->name, &(hmm->codebook_root));
00071     }
00072   }
00073 }
00074 
00091 static void
00092 tmix_create_codebook_index(HTK_HMM_INFO *hmminfo, GCODEBOOK *book)
00093 {
00094   char *mixname;
00095   HTK_HMM_Dens *dtmp;
00096   int i;
00097   int realbooknum = 0;
00098 
00099   mixname = (char *)mymalloc(strlen(book->name)+30);
00100   book->d = (HTK_HMM_Dens **) mybmalloc2(sizeof(HTK_HMM_Dens *) * book->num, &(hmminfo->mroot));
00101   for (i=0;i<book->num;i++) {
00102     sprintf(mixname, "%s%d", book->name, i + 1);
00103     if ((dtmp = dens_lookup(hmminfo, mixname)) == NULL) {
00104 
00105 
00106 
00107 
00108       book->d[i] = NULL;
00109     } else {
00110       book->d[i] = dtmp;
00111       realbooknum++;
00112     }
00113   }
00114   if (realbooknum < book->num) {
00115     jlog("Warning: rdhmmdef_tiedmix: book [%s]: defined=%d < %d\n",
00116          book->name, realbooknum, book->num);
00117   }
00118   
00119   free(mixname);
00120 }
00121 
00136 void
00137 tmix_read(FILE *fp, HTK_HMM_State *state, HTK_HMM_INFO *hmm)
00138 {
00139   char *bookname;
00140   GCODEBOOK *thebook;
00141   int mid, i;
00142 
00143   NoTokErr("missing TMIX bookname");
00144   bookname = rdhmmdef_token;
00145   
00146   if ((thebook = codebook_lookup(hmm, bookname)) == NULL) {
00147     
00148     thebook = (GCODEBOOK *)mybmalloc2(sizeof(GCODEBOOK), &(hmm->mroot));
00149     thebook->name = mybstrdup2(bookname, &(hmm->mroot));
00150     thebook->num = state->mix_num;
00151     
00152     tmix_create_codebook_index(hmm, thebook);
00153     
00154     codebook_add(hmm, thebook);
00155     thebook->id = hmm->codebooknum;
00156     hmm->codebooknum++;
00157     
00158     if (hmm->maxcodebooksize < thebook->num) hmm->maxcodebooksize = thebook->num;
00159   } else {
00160     
00161     if (state->mix_num != thebook->num) {
00162       rderr("tmix_read: TMIX weight num don't match the codebook size");
00163     }
00164   }
00165 
00166   
00167   state->b = (HTK_HMM_Dens **)thebook;
00168 
00169   
00170   read_token(fp);
00171   state->bweight = (PROB *) mybmalloc2(sizeof(PROB) * state->mix_num, &(hmm->mroot));
00172   {
00173     int len;
00174     double w;
00175 
00176     mid = 0;
00177     while (mid < state->mix_num)
00178     {
00179       char *p, q;
00180       NoTokErr("missing some TMIX weights");
00181       if ((p = strchr(rdhmmdef_token, '*')) == NULL) {
00182         len = 1;
00183         w = atof(rdhmmdef_token);
00184       } else {
00185         len = atoi(p+1);
00186         q = *p;
00187         *p = '\0';
00188         w = atof(rdhmmdef_token);
00189         *p = q;
00190       }
00191       read_token(fp);
00192       for(i=0;i<len;i++) {
00193         state->bweight[mid] = (PROB)log(w);
00194         mid++;
00195       }
00196     }
00197   }
00198 
00199   
00200   hmm->is_tied_mixture = TRUE;
00201 }
00202