Julius 4.2
libsent/src/hmminfo/rdhmmdef_mpdf.c
説明を見る。
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 */