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