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
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
00065 new->next = hmm->pdfstart;
00066 hmm->pdfstart = new;
00067
00068 if (new->name != NULL) {
00069
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
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
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
00157 new->mix_num = 1;
00158 }
00159 }
00160
00161 if (currentis("TMIX")) {
00162 read_token(fp);
00163
00164 tmix_read(fp, new, hmm);
00165
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) {
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
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
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;
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
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
00277 new->name = name;
00278 mpdf_add(hmm, new);
00279 }
00280
00281