/* * Compute the top-N closest gaussians from the chosen set (mgau,feat) * for the given input observation vector. */ static int32 compute_dist(gauden_dist_t * out_dist, int32 n_top, mfcc_t * obs, int32 featlen, mfcc_t ** mean, mfcc_t ** var, mfcc_t * det, int32 n_density) { int32 i, j, d; gauden_dist_t *worst; /* Special case optimization when n_density <= n_top */ if (n_top >= n_density) return (compute_dist_all (out_dist, obs, featlen, mean, var, det, n_density)); for (i = 0; i < n_top; i++) out_dist[i].dist = WORST_DIST; worst = &(out_dist[n_top - 1]); for (d = 0; d < n_density; d++) { mfcc_t *m; mfcc_t *v; mfcc_t dval; m = mean[d]; v = var[d]; dval = det[d]; for (i = 0; (i < featlen) && (dval >= worst->dist); i++) { mfcc_t diff; #ifdef FIXED_POINT /* Have to check for underflows here. */ mfcc_t pdval = dval; diff = obs[i] - m[i]; dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]); if (dval > pdval) { dval = WORST_SCORE; break; } #else diff = obs[i] - m[i]; /* The compiler really likes this to be a single * expression, for whatever reason. */ dval -= diff * diff * v[i]; #endif } if ((i < featlen) || (dval < worst->dist)) /* Codeword d worse than worst */ continue; /* Codeword d at least as good as worst so far; insert in the ordered list */ for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++); assert(i < n_top); for (j = n_top - 1; j > i; --j) out_dist[j] = out_dist[j - 1]; out_dist[i].dist = dval; out_dist[i].id = d; } return 0; }
static void eval_cb(s2_semi_mgau_t *s, int32 feat, mfcc_t *z) { vqFeature_t *worst, *best, *topn; mfcc_t *mean; mfcc_t *var, *det, *detP, *detE; int32 i, ceplen; best = topn = s->f[feat]; worst = topn + (s->max_topn - 1); mean = s->means[feat][0]; var = s->vars[feat][0]; det = s->dets[feat]; detE = det + s->n_density; ceplen = s->veclen[feat]; for (detP = det; detP < detE; ++detP) { mfcc_t diff, sqdiff, compl; /* diff, diff^2, component likelihood */ mfcc_t d; mfcc_t *obs; vqFeature_t *cur; int32 cw, j; d = *detP; obs = z; cw = detP - det; for (j = 0; (j < ceplen) && (d >= worst->score); ++j) { diff = *obs++ - *mean++; sqdiff = MFCCMUL(diff, diff); compl = MFCCMUL(sqdiff, *var); d = GMMSUB(d, compl); ++var; } if (j < ceplen) { /* terminated early, so not in topn */ mean += (ceplen - j); var += (ceplen - j); continue; } if ((int32)d < worst->score) continue; for (i = 0; i < s->max_topn; i++) { /* already there, so don't need to insert */ if (topn[i].codeword == cw) break; } if (i < s->max_topn) continue; /* already there. Don't insert */ /* remaining code inserts codeword and dist in correct spot */ for (cur = worst - 1; cur >= best && (int32)d >= cur->score; --cur) memcpy(cur + 1, cur, sizeof(vqFeature_t)); ++cur; cur->codeword = cw; cur->score = (int32)d; } }
static void eval_cb_kdtree(s2_semi_mgau_t *s, int32 feat, mfcc_t *z, kd_tree_node_t *node, uint32 maxbbi) { vqFeature_t *worst, *best, *topn; int32 i, ceplen; best = topn = s->f[feat]; worst = topn + (s->max_topn - 1); ceplen = s->veclen[feat]; for (i = 0; i < maxbbi; ++i) { mfcc_t *mean, diff, sqdiff, compl; /* diff, diff^2, component likelihood */ mfcc_t *var, d; mfcc_t *obs; vqFeature_t *cur; int32 cw, j, k; cw = node->bbi[i]; mean = s->means[feat] + cw * ceplen; var = s->vars[feat] + cw * ceplen; d = s->dets[feat][cw]; obs = z; for (j = 0; (j < ceplen) && (d >= worst->score); j++) { diff = *obs++ - *mean++; sqdiff = MFCCMUL(diff, diff); compl = MFCCMUL(sqdiff, *var); d = GMMSUB(d, compl); ++var; } if (j < ceplen) continue; if ((int32)d < worst->score) continue; for (k = 0; k < s->max_topn; k++) { /* already there, so don't need to insert */ if (topn[k].codeword == cw) break; } if (k < s->max_topn) continue; /* already there. Don't insert */ /* remaining code inserts codeword and dist in correct spot */ for (cur = worst - 1; cur >= best && (int32)d >= cur->score; --cur) memcpy(cur + 1, cur, sizeof(vqFeature_t)); ++cur; cur->codeword = cw; cur->score = (int32)d; } }
static void cmn_prior_shiftwin(cmn_t *cmn) { mfcc_t sf; int32 i; E_INFO("cmn_prior_update: from < "); for (i = 0; i < cmn->veclen; i++) E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i])); E_INFOCONT(">\n"); sf = FLOAT2MFCC(1.0) / cmn->nframe; for (i = 0; i < cmn->veclen; i++) cmn->cmn_mean[i] = cmn->sum[i] / cmn->nframe; /* sum[i] * sf */ /* Make the accumulation decay exponentially */ if (cmn->nframe >= CMN_WIN_HWM) { sf = CMN_WIN * sf; for (i = 0; i < cmn->veclen; i++) cmn->sum[i] = MFCCMUL(cmn->sum[i], sf); cmn->nframe = CMN_WIN; } E_INFO("cmn_prior_update: to < "); for (i = 0; i < cmn->veclen; i++) E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i])); E_INFOCONT(">\n"); }
/* See compute_dist below */ static int32 compute_dist_all(gauden_dist_t * out_dist, mfcc_t* obs, int32 featlen, mfcc_t ** mean, mfcc_t ** var, mfcc_t * det, int32 n_density) { int32 i, d; for (d = 0; d < n_density; ++d) { mfcc_t *m; mfcc_t *v; mfcc_t dval; m = mean[d]; v = var[d]; dval = det[d]; for (i = 0; i < featlen; i++) { mfcc_t diff; #ifdef FIXED_POINT /* Have to check for underflows here. */ mfcc_t pdval = dval; diff = obs[i] - m[i]; dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]); if (dval > pdval) { dval = WORST_SCORE; break; } #else diff = obs[i] - m[i]; /* The compiler really likes this to be a single * expression, for whatever reason. */ dval -= diff * diff * v[i]; #endif } out_dist[d].dist = dval; out_dist[d].id = d; } return 0; }
static void eval_topn(s2_semi_mgau_t *s, int32 feat, mfcc_t *z) { int i, ceplen; vqFeature_t *topn; topn = s->f[feat]; ceplen = s->veclen[feat]; for (i = 0; i < s->max_topn; i++) { mfcc_t *mean, diff, sqdiff, compl; /* diff, diff^2, component likelihood */ vqFeature_t vtmp; mfcc_t *var, d; mfcc_t *obs; int32 cw, j; cw = topn[i].codeword; mean = s->means[feat][0] + cw * ceplen; var = s->vars[feat][0] + cw * ceplen; d = s->dets[feat][cw]; obs = z; for (j = 0; j < ceplen; j++) { diff = *obs++ - *mean++; sqdiff = MFCCMUL(diff, diff); compl = MFCCMUL(sqdiff, *var); d = GMMSUB(d, compl); ++var; } topn[i].score = (int32)d; if (i == 0) continue; vtmp = topn[i]; for (j = i - 1; j >= 0 && (int32)d > topn[j].score; j--) { topn[j + 1] = topn[j]; } topn[j + 1] = vtmp; } }
void feat_lda_transform(feat_t *fcb, mfcc_t ***inout_feat, uint32 nfr) { mfcc_t *tmp; uint32 i, j, k; tmp = ckd_calloc(fcb->stream_len[0], sizeof(mfcc_t)); for (i = 0; i < nfr; ++i) { /* Do the matrix multiplication inline here since fcb->lda * is transposed (eigenvectors in rows not columns). */ /* FIXME: In the future we ought to use the BLAS. */ memset(tmp, 0, sizeof(mfcc_t) * fcb->stream_len[0]); for (j = 0; j < feat_dimension(fcb); ++j) { for (k = 0; k < fcb->stream_len[0]; ++k) { tmp[j] += MFCCMUL(inout_feat[i][0][k], fcb->lda[0][j][k]); } } memcpy(inout_feat[i][0], tmp, fcb->stream_len[0] * sizeof(mfcc_t)); } ckd_free(tmp); }
void cmn(cmn_t *cmn, mfcc_t ** mfc, int32 varnorm, int32 n_frame) { mfcc_t *mfcp; mfcc_t t; int32 i, f; oe_assert(mfc != NULL); if (n_frame <= 0) return; /* If cmn->cmn_mean wasn't NULL, we need to zero the contents */ memset(cmn->cmn_mean, 0, cmn->veclen * sizeof(mfcc_t)); /* Find mean cep vector for this utterance */ for (f = 0; f < n_frame; f++) { mfcp = mfc[f]; for (i = 0; i < cmn->veclen; i++) { cmn->cmn_mean[i] += mfcp[i]; } } for (i = 0; i < cmn->veclen; i++) cmn->cmn_mean[i] /= n_frame; E_INFO("CMN: "); for (i = 0; i < cmn->veclen; i++) E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i])); E_INFOCONT("\n"); if (!varnorm) { /* Subtract mean from each cep vector */ for (f = 0; f < n_frame; f++) { mfcp = mfc[f]; for (i = 0; i < cmn->veclen; i++) mfcp[i] -= cmn->cmn_mean[i]; } } else { /* Scale cep vectors to have unit variance along each dimension, and subtract means */ /* If cmn->cmn_var wasn't NULL, we need to zero the contents */ memset(cmn->cmn_var, 0, cmn->veclen * sizeof(mfcc_t)); for (f = 0; f < n_frame; f++) { mfcp = mfc[f]; for (i = 0; i < cmn->veclen; i++) { t = mfcp[i] - cmn->cmn_mean[i]; cmn->cmn_var[i] += MFCCMUL(t, t); } } for (i = 0; i < cmn->veclen; i++) /* Inverse Std. Dev, RAH added type case from sqrt */ cmn->cmn_var[i] = FLOAT2MFCC(sqrt((float64)n_frame / MFCC2FLOAT(cmn->cmn_var[i]))); for (f = 0; f < n_frame; f++) { mfcp = mfc[f]; for (i = 0; i < cmn->veclen; i++) mfcp[i] = MFCCMUL((mfcp[i] - cmn->cmn_mean[i]), cmn->cmn_var[i]); } } }