📄 subvq.c
字号:
if ((fscanf (fp, "%s", line) != 1) || (strcmp (line, "End") != 0)) E_FATAL("Error reading 'End' token\n"); fclose (fp); subvq_maha_precomp (vq, varfloor); subvq_map_compact (vq, g); subvq_map_linearize (vq); n = 0; for (s = 0; s < n_sv; s++) { if (vq->gautbl[s].veclen > n) n = vq->gautbl[s].veclen; } assert (n > 0); vq->subvec = (float32 *) ckd_calloc (n, sizeof(float32)); vq->vqdist = (int32 **) ckd_calloc_2d (vq->n_sv, vq->vqsize, sizeof(int32)); vq->gauscore = (int32 *) ckd_calloc (vq->origsize.c, sizeof(int32)); vq->mgau_sl = (int32 *) ckd_calloc (vq->origsize.c + 1, sizeof(int32)); return vq;}/* * Based on previously computed subvq scores (Mahalanobis distances), determine the active * components in the given mixture (using the vq->map). * Return value: #Candidates in the returned shortlist. */int32 subvq_mgau_shortlist (subvq_t *vq, int32 m, /* In: Mixture index */ int32 n, /* In: #Components in specified mixture */ int32 beam) /* In: Threshold to select active components */{ int32 *gauscore; int32 *map; int32 i, v, bv, th, nc; int32 *sl; int32 *vqdist; int32 sv_id; vqdist = vq->vqdist[0]; /* Since map is linearized for efficiency, must also look at vqdist[][] as vqdist[] */ gauscore = vq->gauscore; sl = vq->mgau_sl; /* Special case when vq->n_sv == 3; for speed */ map = vq->map[m][0]; bv = MAX_NEG_INT32; switch (vq->n_sv) { case 3: for (i = 0; i < n; i++) { if (vq->VQ_EVAL == 1) { v = (int32) vqdist[*map];/* If we are not weighting the cep values, we need to adjust the subvqbeam */ map += 3; } else { /* RAH, we are ignoring the delta-delta, scoring the delta twice, strangely this works better than weighting the scores */ /* I believe it has to do with the beam widths */ if (vq->VQ_EVAL == 2) { v = vqdist[*(map++)]; v += 2 * vqdist[*map]; /* RAH Count delta twice, we can keep the same subvqbeam as vq_eval = 3 if we double the delta*/ map += 2; } else { v = vqdist[*(map++)];/* Standard way */ v += vqdist[*(map++)]; /* */ v += vqdist[*(map++)]; /* */ } } gauscore[i] = v; if (bv < v) bv = v; } break; case 2: for (i = 0; i < n; i++) { v = vqdist[*(map++)]; v += vqdist[*(map++)]; gauscore[i] = v; if (bv < v) bv = v; } break; case 1: for (i = 0; i < n; i++) { v = vqdist[*(map++)]; gauscore[i] = v; if (bv < v) bv = v; } break; default: for (i = 0; i < n; i++) { v=0; for(sv_id =0 ; sv_id<vq->n_sv; sv_id++){ v+=vqdist[*(map++)]; } gauscore[i] = v; if (bv < v) bv = v; } } th = bv + beam; nc = 0; for (i = 0; i < n; i++) { if (gauscore[i] >= th) sl[nc++] = i; } sl[nc] = -1; return nc;}void subvq_subvec_eval_logs3 (subvq_t *vq, float32 *feat, int32 s){ int32 i; int32 *featdim; /* Extract subvector from feat */ featdim = vq->featdim[s]; for (i = 0; i < vq->gautbl[s].veclen; i++) vq->subvec[i] = feat[featdim[i]]; /* Evaluate distances between extracted subvector and corresponding codebook */ vector_gautbl_eval_logs3(&(vq->gautbl[s]), 0, vq->vqsize, vq->subvec, vq->vqdist[s]);}void subvq_gautbl_eval_logs3 (subvq_t *vq, float32 *feat){ int32 s, i; int32 *featdim; for (s = 0; s < vq->n_sv; s++) { /* Extract subvector from feat */ featdim = vq->featdim[s]; for (i = 0; i < vq->gautbl[s].veclen; i++) vq->subvec[i] = feat[featdim[i]]; /* Evaluate distances between extracted subvector and corresponding codebook */ /* RAH, only evaluate the first VQ_EVAL set of features */ if (s < vq->VQ_EVAL) vector_gautbl_eval_logs3(&(vq->gautbl[s]), 0, vq->vqsize, vq->subvec, vq->vqdist[s]); }}int32 subvq_frame_eval (subvq_t *vq, mgau_model_t *g, int32 beam, float32 *feat, int32 *sen_active, int32 *senscr){ int32 s; int32 best, ns, ng; best = MAX_NEG_INT32; ns = 0; ng = 0; if (! vq) { /* No subvq model, use the original (SLOW!!) */ for (s = 0; s < g->n_mgau; s++) { if ((! sen_active) || sen_active[s]) { senscr[s] = mgau_eval (g, s, NULL, feat); if (best < senscr[s]) best = senscr[s]; ns++; ng += mgau_n_comp (g, s); } else senscr[s] = S3_LOGPROB_ZERO; } } else { /* Evaluate subvq model for given feature vector */ subvq_gautbl_eval_logs3 (vq, feat); /* Find mixture component shortlists using subvq scores, and evaluate senones */ for (s = 0; s < g->n_mgau; s++) { if ((! sen_active) || sen_active[s]) { ng += subvq_mgau_shortlist (vq, s, mgau_n_comp(g,s), beam); senscr[s] = mgau_eval (g, s, vq->mgau_sl, feat); if (best < senscr[s]) best = senscr[s]; ns++; } else senscr[s] = S3_LOGPROB_ZERO; } } /* Normalize senone scores */ for (s = 0; s < g->n_mgau; s++) senscr[s] -= best; g->frm_sen_eval = ns; g->frm_gau_eval = ng; return best;}int32 subvq_mgau_eval (mgau_model_t *g, subvq_t *vq, int32 m, int32 n, int32 *active){ mgau_t *mgau; int32 *map; int32 i, v, sv_id; int32 c; int32 *vqdist; int32 score; int32 last_active; float64 f; f = log_to_logs3_factor(); vqdist = vq->vqdist[0]; score = S3_LOGPROB_ZERO; mgau = &(g->mgau[m]); map = vq->map[m][0]; if(!active){ for (i = 0; i < n; i++) { v=0; for(sv_id =0 ; sv_id<vq->n_sv; sv_id++){ v+=vqdist[*(map++)]; } score = logs3_add (score, v + mgau->mixw[i]); } }else{ last_active=0; for (i = 0; active[i] >=0; i++) { c=active[i]; } for (i = 0; active[i] >=0; i++) { c=active[i]; map+=(c-last_active)*vq->n_sv; v=0; for(sv_id =0 ; sv_id<vq->n_sv; sv_id++){ v+=vqdist[*(map++)]; } last_active=c+1; score = logs3_add (score, v + mgau->mixw[i]); } } if(score == S3_LOGPROB_ZERO){ E_INFO("Warning!! Score is S3_LOGPROB_ZERO\n"); } return score;}/* RAH, free memory allocated by subvq_init() */void subvq_free (subvq_t *s){ int i; if (s) { for (i=0;i<s->n_sv;i++) { // vector_gautbl_free (&(s->gautbl[i])); if (s->featdim[i]) ckd_free ((void *) s->featdim[i]); } if (s->featdim) ckd_free ((void *) s->featdim); /* Free gaussian table */ if (s->gautbl) ckd_free ((void *)s->gautbl); /* Free map */ if (s->map) ckd_free_3d ((void ***) s->map); if (s->subvec) ckd_free ((void *) s->subvec); if (s->vqdist) ckd_free_2d ((void **) s->vqdist); if (s->gauscore) ckd_free ((void *) s->gauscore); if (s->mgau_sl) ckd_free ((void *) s->mgau_sl); ckd_free ((void *)s); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -