Julius 4.2
|
00001 00018 /* 00019 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00020 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00021 * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology 00022 * All rights reserved 00023 */ 00024 00025 #include <sent/stddefs.h> 00026 #include <sent/htk_hmm.h> 00027 00028 extern char *rdhmmdef_token; 00029 00035 static HTK_HMM_PDF * 00036 mpdf_new(HTK_HMM_INFO *hmm) 00037 { 00038 HTK_HMM_PDF *new; 00039 00040 new = (HTK_HMM_PDF *)mybmalloc2(sizeof(HTK_HMM_PDF), &(hmm->mroot)); 00041 00042 new->name = NULL; 00043 new->tmix = FALSE; 00044 new->stream_id = -1; 00045 new->mix_num = 0; 00046 new->b = NULL; 00047 new->bweight = NULL; 00048 new->next = NULL; 00049 00050 return(new); 00051 } 00052 00059 void 00060 mpdf_add(HTK_HMM_INFO *hmm, HTK_HMM_PDF *new) 00061 { 00062 HTK_HMM_PDF *match; 00063 00064 /* link data structure */ 00065 new->next = hmm->pdfstart; 00066 hmm->pdfstart = new; 00067 00068 if (new->name != NULL) { 00069 /* add index to search index tree */ 00070 if (hmm->pdf_root == NULL) { 00071 hmm->pdf_root = aptree_make_root_node(new, &(hmm->mroot)); 00072 } else { 00073 match = aptree_search_data(new->name, hmm->pdf_root); 00074 if (match != NULL && strmatch(match->name, new->name)) { 00075 jlog("Error: rdhmmdef_dens: ~m \"%s\" is already defined\n", new->name); 00076 rderr(NULL); 00077 } else { 00078 aptree_add_entry(new->name, new, match->name, &(hmm->pdf_root), &(hmm->mroot)); 00079 } 00080 } 00081 } 00082 } 00083 00092 HTK_HMM_PDF * 00093 mpdf_lookup(HTK_HMM_INFO *hmm, char *keyname) 00094 { 00095 HTK_HMM_PDF *d; 00096 00097 d = aptree_search_data(keyname, hmm->pdf_root); 00098 if (d != NULL && strmatch(d->name, keyname)) { 00099 return d; 00100 } else { 00101 return NULL; 00102 } 00103 } 00104 00120 static HTK_HMM_PDF * 00121 mpdf_read(FILE *fp, HTK_HMM_INFO *hmm, int mix_num) 00122 { 00123 HTK_HMM_PDF *new; 00124 int i, mid; 00125 boolean no_nummixes; 00126 00127 new = mpdf_new(hmm); 00128 00129 /* allow <Stream> inside pdf */ 00130 if (currentis("STREAM")) { 00131 read_token(fp); 00132 NoTokErr("missing STREAM value"); 00133 new->stream_id = atoi(rdhmmdef_token) - 1; 00134 read_token(fp); 00135 } 00136 00137 /* allow <NumMixes> in stream definition */ 00138 if (mix_num == -1) { 00139 no_nummixes = TRUE; 00140 } else { 00141 no_nummixes = FALSE; 00142 } 00143 if (currentis("NUMMIXES")) { 00144 read_token(fp); 00145 new->mix_num = atoi(rdhmmdef_token); 00146 if (mix_num != -1 && new->mix_num != mix_num) { 00147 jlog("Error: rdhmmdef_mpdf: <NumMixes> exists both in mpdf definition and its referer, and the values are different (%d != %d)\n", new->mix_num, mix_num); 00148 rderr(NULL); 00149 } 00150 read_token(fp); 00151 no_nummixes = FALSE; 00152 } else { 00153 if (mix_num != -1) { 00154 new->mix_num = mix_num; 00155 } else { 00156 /* no NumMixes, assume single gaussian */ 00157 new->mix_num = 1; 00158 } 00159 } 00160 00161 if (currentis("TMIX")) { 00162 read_token(fp); 00163 /* read in TMIX */ 00164 tmix_read(fp, new, hmm); 00165 /* mark this */ 00166 new->tmix = TRUE; 00167 00168 } else { 00169 00170 new->b = (HTK_HMM_Dens **) mybmalloc2(sizeof(HTK_HMM_Dens *) * new->mix_num, &(hmm->mroot)); 00171 new->bweight = (PROB *) mybmalloc2(sizeof(PROB) * new->mix_num, &(hmm->mroot)); 00172 for (i=0;i<new->mix_num;i++) { 00173 new->b[i] = NULL; 00174 new->bweight[i] = LOG_ZERO; 00175 } 00176 00177 if (no_nummixes) { /* no NumMixes */ 00178 mid = 0; 00179 new->bweight[mid] = 0.0; 00180 new->b[mid] = get_dens_data(fp, hmm); 00181 } else { 00182 for (;;) { 00183 if (!currentis("MIXTURE")) break; 00184 read_token(fp); 00185 NoTokErr("missing MIXTURE id"); 00186 mid = atoi(rdhmmdef_token) - 1; 00187 read_token(fp); 00188 NoTokErr("missing MIXTURE weight"); 00189 new->bweight[mid] = (PROB)log(atof(rdhmmdef_token)); 00190 read_token(fp); 00191 new->b[mid] = get_dens_data(fp, hmm); 00192 } 00193 } 00194 00195 new->tmix = FALSE; 00196 } 00197 00198 return (new); 00199 } 00200 00216 HTK_HMM_PDF * 00217 get_mpdf_data(FILE *fp, HTK_HMM_INFO *hmm, int mix_num, short stream_id) 00218 { 00219 HTK_HMM_PDF *tmp = NULL; 00220 00221 if (currentis("~p")) { 00222 /* macro reference: lookup and return the pointer */ 00223 read_token(fp); 00224 NoTokErr("missing macro name"); 00225 tmp = mpdf_lookup(hmm, rdhmmdef_token); 00226 if (tmp == NULL) { 00227 jlog("Error: rdhmmdef_mpdf: ~p \"%s\" not defined\n", rdhmmdef_token); 00228 rderr(NULL); 00229 } 00230 if (mix_num != -1 && tmp->mix_num != mix_num) { 00231 jlog("Error: rdhmmdef_mpdf: mixture num in ~p \"%s\" definition and referer is different (%d != %d)\n", rdhmmdef_token, tmp->mix_num, mix_num); 00232 rderr(NULL); 00233 } 00234 if (tmp->stream_id != stream_id) { 00235 jlog("Error: rdhmmdef_mpdf: stream number in ~p \"%s\" definition and referer is different (%d != %d)\n", rdhmmdef_token, tmp->stream_id + 1, stream_id + 1); 00236 rderr(NULL); 00237 } 00238 read_token(fp); 00239 } else if (currentis("NUMMIXES")||currentis("MIXTURE")||currentis("TMIX")||currentis("MEAN")||currentis("~m")||currentis("RCLASS")) { 00240 /* definition: define density data, and return the pointer */ 00241 tmp = mpdf_read(fp, hmm, mix_num); 00242 if (tmp->stream_id == -1) { 00243 tmp->stream_id = stream_id; 00244 } else if (tmp->stream_id != stream_id) { 00245 jlog("Error: rdhmmdef_mpdf: stream number exist in inline mpdf definition and referer is different (%d != %d)\n", rdhmmdef_token, tmp->stream_id + 1, stream_id + 1); 00246 rderr(NULL); 00247 } 00248 tmp->name = NULL; /* no name */ 00249 mpdf_add(hmm, tmp); 00250 } else { 00251 rderr("syntax error: not mixture pdf data"); 00252 } 00253 return tmp; 00254 } 00255 00256 00264 void 00265 def_mpdf_macro(char *name, FILE *fp, HTK_HMM_INFO *hmm) 00266 { 00267 HTK_HMM_PDF *new; 00268 00269 /* read in data and return newly malloced data */ 00270 new = mpdf_read(fp, hmm, -1); 00271 if (new->stream_id == -1) { 00272 jlog("Error: rdhmmdef_pdf: definition of ~p \"%s\" has no <Stream>\n", name); 00273 rderr(NULL); 00274 } 00275 00276 /* register it to the grobal HMM structure */ 00277 new->name = name; 00278 mpdf_add(hmm, new); 00279 } 00280 00281 /* end of file */