00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #include "ms_mgau.h"
00073
00074 static ps_mgaufuncs_t ms_mgau_funcs = {
00075 "ms",
00076 &ms_cont_mgau_frame_eval,
00077 &ms_mgau_mllr_transform,
00078 &ms_mgau_free
00079 };
00080
00081 ps_mgau_t *
00082 ms_mgau_init(cmd_ln_t *config, logmath_t *lmath)
00083 {
00084
00085 int32 i;
00086 ms_mgau_model_t *msg;
00087 ps_mgau_t *mg;
00088 gauden_t *g;
00089 senone_t *s;
00090 mgau2sen_t *m2s;
00091
00092 msg = (ms_mgau_model_t *) ckd_calloc(1, sizeof(ms_mgau_model_t));
00093
00094 msg->g = NULL;
00095 msg->s = NULL;
00096
00097 msg->g = gauden_init(cmd_ln_str_r(config, "-mean"),
00098 cmd_ln_str_r(config, "-var"),
00099 cmd_ln_float32_r(config, "-varfloor"),
00100 lmath);
00101 msg->s = senone_init(msg->g,
00102 cmd_ln_str_r(config, "-mixw"), NULL,
00103 cmd_ln_float32_r(config, "-mixwfloor"), lmath);
00104
00105 g = ms_mgau_gauden(msg);
00106 s = ms_mgau_senone(msg);
00107
00108
00109 if (s->n_feat != g->n_feat)
00110 E_FATAL("#Feature mismatch: gauden= %d, senone= %d\n", g->n_feat,
00111 s->n_feat);
00112 if (s->n_cw != g->n_density)
00113 E_FATAL("#Densities mismatch: gauden= %d, senone= %d\n",
00114 g->n_density, s->n_cw);
00115 if (s->n_gauden > g->n_mgau)
00116 E_FATAL("Senones need more codebooks (%d) than present (%d)\n",
00117 s->n_gauden, g->n_mgau);
00118 if (s->n_gauden < g->n_mgau)
00119 E_ERROR("Senones use fewer codebooks (%d) than present (%d)\n",
00120 s->n_gauden, g->n_mgau);
00121
00122 msg->mgau2sen =
00123 (mgau2sen_t **) ckd_calloc(g->n_mgau, sizeof(mgau2sen_t *));
00124 for (i = 0; i < s->n_sen; i++) {
00125 m2s = (mgau2sen_t *) ckd_calloc(1, sizeof(mgau2sen_t));
00126 m2s->sen = i;
00127 m2s->next = msg->mgau2sen[s->mgau[i]];
00128 msg->mgau2sen[s->mgau[i]] = m2s;
00129 }
00130
00131 msg->topn = cmd_ln_int32_r(config, "-topn");
00132 E_INFO("The value of topn: %d\n", msg->topn);
00133 if (msg->topn == 0 || msg->topn > msg->g->n_density) {
00134 E_WARN
00135 ("-topn argument (%d) invalid or > #density codewords (%d); set to latter\n",
00136 msg->topn, msg->g->n_density);
00137 msg->topn = msg->g->n_density;
00138 }
00139
00140 msg->dist = (gauden_dist_t ***)
00141 ckd_calloc_3d(g->n_mgau, g->n_feat, msg->topn,
00142 sizeof(gauden_dist_t));
00143 msg->mgau_active = ckd_calloc(g->n_mgau, sizeof(int8));
00144
00145 mg = (ps_mgau_t *)msg;
00146 mg->vt = &ms_mgau_funcs;
00147 return mg;
00148 }
00149
00150 void
00151 ms_mgau_free(ps_mgau_t * mg)
00152 {
00153 ms_mgau_model_t *msg = (ms_mgau_model_t *)mg;
00154 if (msg == NULL)
00155 return;
00156
00157 gauden_free(msg->g);
00158 senone_free(msg->s);
00159 ckd_free_3d((void *) msg->dist);
00160 ckd_free(msg->mgau_active);
00161 ckd_free(msg);
00162 }
00163
00164 int
00165 ms_mgau_mllr_transform(ps_mgau_t *s,
00166 ps_mllr_t *mllr)
00167 {
00168 return -1;
00169 }
00170
00171 int32
00172 ms_cont_mgau_frame_eval(ps_mgau_t * mg,
00173 int16 *senscr,
00174 uint8 *senone_active,
00175 int32 n_senone_active,
00176 mfcc_t ** feat,
00177 int32 frame,
00178 int32 compallsen)
00179 {
00180 ms_mgau_model_t *msg = (ms_mgau_model_t *)mg;
00181 int32 gid;
00182 int32 topn;
00183 int32 best;
00184 gauden_t *g;
00185 senone_t *sen;
00186
00187 topn = ms_mgau_topn(msg);
00188 g = ms_mgau_gauden(msg);
00189 sen = ms_mgau_senone(msg);
00190
00191 if (compallsen) {
00192 int32 s;
00193
00194 for (gid = 0; gid < g->n_mgau; gid++)
00195 gauden_dist(g, gid, topn, feat, msg->dist[gid]);
00196
00197 best = (int32) 0x7fffffff;
00198 for (s = 0; s < sen->n_sen; s++) {
00199 senscr[s] = senone_eval(sen, s, msg->dist[sen->mgau[s]], topn);
00200 if (best > senscr[s]) {
00201 best = senscr[s];
00202 }
00203 }
00204
00205
00206 for (s = 0; s < sen->n_sen; s++) {
00207 int32 bs = senscr[s] - best;
00208 if (bs > 32767)
00209 bs = 32767;
00210 if (bs < -32768)
00211 bs = -32768;
00212 senscr[s] = bs;
00213 }
00214 }
00215 else {
00216 int32 i, n;
00217
00218 for (gid = 0; gid < g->n_mgau; gid++)
00219 msg->mgau_active[gid] = 0;
00220
00221 n = 0;
00222 for (i = 0; i < n_senone_active; i++) {
00223
00224 int32 s = senone_active[i] + n;
00225 msg->mgau_active[sen->mgau[s]] = 1;
00226 n = s;
00227 }
00228
00229
00230 for (gid = 0; gid < g->n_mgau; gid++) {
00231 if (msg->mgau_active[gid])
00232 gauden_dist(g, gid, topn, feat, msg->dist[gid]);
00233 }
00234
00235 best = (int32) 0x7fffffff;
00236 n = 0;
00237 for (i = 0; i < n_senone_active; i++) {
00238 int32 s = senone_active[i] + n;
00239 senscr[s] = senone_eval(sen, s, msg->dist[sen->mgau[s]], topn);
00240 if (best > senscr[s]) {
00241 best = senscr[s];
00242 }
00243 n = s;
00244 }
00245
00246
00247 n = 0;
00248 for (i = 0; i < n_senone_active; i++) {
00249 int32 s = senone_active[i] + n;
00250 int32 bs = senscr[s] - best;
00251 if (bs > 32767)
00252 bs = 32767;
00253 if (bs < -32768)
00254 bs = -32768;
00255 senscr[s] = bs;
00256 n = s;
00257 }
00258 }
00259
00260 return 0;
00261 }