📄 subvq.c
字号:
/* ==================================================================== * Copyright (c) 1999-2004 Carnegie Mellon University. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * This work was supported in part by funding from the Defense Advanced * Research Projects Agency and the National Science Foundation of the * United States of America, and the CMU Sphinx Speech Consortium. * * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ==================================================================== * *//* * subvq.c * * ********************************************** * CMU ARPA Speech Project * * Copyright (c) 1999 Carnegie Mellon University. * ALL RIGHTS RESERVED. * ********************************************** * * HISTORY * * 20.Apr.2001 RAH (rhoughton@mediasite.com, ricky.houghton@cs.cmu.edu) * Updated subvq_free () to free allocated memory * * 17-Dec-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Added handling of a single sub-vector in subvq_mgau_shortlist(). * * 15-Dec-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Changes due to moving subvq_t.{frm_sen_eval,frm_gau_eval} to cont_mgau.h. * * 14-Dec-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Added subvq_t.{frm_sen_eval,frm_gau_eval}. Changed subvq_frame_eval to * return the normalization factor. * * 06-Dec-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Added subvq_subvec_eval_logs3(). * * 14-Oct-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Changed ci_active flags input to sen_active in subvq_frame_eval(). * * 21-Jul-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Bugfix in subvq_init() that used g for allocating working areas, even * though g wasn't defined. * * 20-Jul-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Added subvq_gautbl_eval_logs3() and used it in subvq_frame_eval(). * * 12-Mar-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * Started. */#include "subvq.h"#include "s3types.h"/* * Precompute variances/(covariance-matrix-determinants) to simplify Mahalanobis distance * calculation. Also, calculate 1/(det) for the original codebooks, based on the VQ vars. * (See comment in libmisc/vector.h.) */static void subvq_maha_precomp (subvq_t *svq, float64 floor){ int32 s; float32 *lrd; vector_gautbl_t *gautbl; E_INFO("Precomputing Mahalanobis distance invariants\n"); lrd = (float32 *) ckd_calloc (svq->n_sv * svq->vqsize, sizeof(float32)); for (s = 0; s < svq->n_sv; s++) { gautbl = &(svq->gautbl[s]); vector_gautbl_var_floor (gautbl, floor); gautbl->lrd = lrd; lrd += svq->vqsize; vector_gautbl_maha_precomp (gautbl); }}static void subvq_map_compact (subvq_t *vq, mgau_model_t *g){ int32 r, c, c2, s; if (g) { if ((g->n_mgau != vq->origsize.r) || (g->max_comp != vq->origsize.c)) E_FATAL("Model size conflict: %d x %d (SubVQ) vs %d x %d (Original)\n", vq->origsize.r, vq->origsize.c, g->n_mgau, g->max_comp); } /* * Compress map entries by removing invalid ones. NOTE: There's not much of a consistency * check to ensure that the entries remaining do map correctly on to the valid entries in * the original (parent) mixture Gaussian model g. The only check we have is to verify * the NUMBER of valid entries (components) in each mixture. */ for (r = 0; r < vq->origsize.r; r++) { for (c = 0, c2 = 0; c < vq->origsize.c; c++) { if (vq->map[r][c][0] < 0) { /* All ought to be < 0 */ for (s = 1; s < vq->n_sv; s++) { if (vq->map[r][c][s] >= 0) E_FATAL("Partially undefined map[%d][%d]\n", r, c); } } else { if (c2 != c) { for (s = 0; s < vq->n_sv; s++) { if (vq->map[r][c][s] < 0) E_FATAL("Partially undefined map[%d][%d]\n", r, c); vq->map[r][c2][s] = vq->map[r][c][s]; } } c2++; } } if (g && (c2 != mgau_n_comp (g, r))) E_FATAL("Mixture %d: #Valid components conflict: %d (SubVQ) vs %d (Original)\n", r, c2, mgau_n_comp(g,r)); /* Invalidate the remaining map entries, for good measure */ for (; c2 < vq->origsize.c; c2++) { for (s = 0; s < vq->n_sv; s++) vq->map[r][c2][s] = -1; } }}/* * At this point, a map entries is an index within the subvector; i.e., map[r][c][s] points to * a subvq codeword within subvector s. In evaluating a complete density using it subvq * component scores, these maps are used, with 2 lookups for each sub-vector. To reduce the * lookups, linearize the map entries by viewing the subvq scores as a linear array rather than * a 2-D array. */static void subvq_map_linearize (subvq_t *vq){ int32 r, c, s; for (r = 0; r < vq->origsize.r; r++) { for (c = 0; (c < vq->origsize.c) && (vq->map[r][c][0] >= 0); c++) { for (s = 0; s < vq->n_sv; s++) vq->map[r][c][s] = (s * vq->vqsize) + vq->map[r][c][s]; } }}subvq_t *subvq_init (char *file, float64 varfloor, int32 max_sv, mgau_model_t *g){ FILE *fp; char line[16384]; int32 n_sv; /* #Subvectors in file, as opposed to that used */ int32 s, k, l, n, r, c; char *strp; subvq_t *vq; vq = (subvq_t *) ckd_calloc (1, sizeof(subvq_t)); vq->VQ_EVAL = cmd_ln_int32 ("-vqeval"); /*Arthur : It nows work for arbitrary size of sub-vector*/ fp = myfopen(file, "r"); E_INFO("Loading Mixture Gaussian sub-VQ file '%s' (vq_eval: %d)\n", file,vq->VQ_EVAL); /* Read until "Sub-vectors" */ for (;;) { if (fgets (line, sizeof(line), fp) == NULL) E_FATAL("Failed to read VQParam header\n"); if (sscanf (line, "VQParam %d %d -> %d %d", &(vq->origsize.r), &(vq->origsize.c), &(vq->n_sv), &(vq->vqsize)) == 4) break; } if (g) { if ((g->n_mgau != vq->origsize.r) || (g->max_comp != vq->origsize.c)) E_FATAL("Model size conflict: %d x %d (SubVQ) vs %d x %d (Original)\n", vq->origsize.r, vq->origsize.c, g->n_mgau, g->max_comp); } if (max_sv < 0) max_sv = vq->n_sv; if (max_sv < vq->n_sv) E_INFO("Using %d subvectors out of %d\n", max_sv, vq->n_sv); else if (max_sv > vq->n_sv) { E_WARN("#Subvectors specified(%d) > available(%d); using latter\n", max_sv, vq->n_sv); max_sv = vq->n_sv; } n_sv = vq->n_sv; vq->n_sv = max_sv; if (vq->n_sv < vq->VQ_EVAL) /* RAH, 5.9.01, sanity check to make sure VQ_EVAL isn't higher than the n_sv */ vq->VQ_EVAL = vq->n_sv; vq->featdim = (int32 **) ckd_calloc (vq->n_sv, sizeof(int32 *)); vq->gautbl = (vector_gautbl_t *) ckd_calloc (vq->n_sv, sizeof(vector_gautbl_t)); vq->map = (int32 ***) ckd_calloc_3d (vq->origsize.r, vq->origsize.c, vq->n_sv, sizeof(int32)); /* Read subvector sizes and feature dimension maps */ for (s = 0; s < n_sv; s++) { if ((fgets (line, sizeof(line), fp) == NULL) || (sscanf (line, "Subvector %d length %d%n", &k, &l, &n) != 2) || (k != s)) E_FATAL("Error reading length(subvector %d)\n", s); if (s < vq->n_sv) { vq->gautbl[s].veclen = l; vq->featdim[s] = (int32 *) ckd_calloc (vq->gautbl[s].veclen, sizeof(int32)); for (strp = line+n, c = 0; c < vq->gautbl[s].veclen; c++) { if (sscanf (strp, "%d%n", &(vq->featdim[s][c]), &n) != 1) E_FATAL("Error reading subvector(%d).featdim(%d)\n", s, c); strp += n; } vector_gautbl_alloc (&(vq->gautbl[s]), vq->vqsize, vq->gautbl[s].veclen); } } /* Echo info for sanity check */ E_INFO("Original #codebooks(states)/codewords: %d x %d\n", vq->origsize.r, vq->origsize.c); E_INFO("Subvectors: %d, VQsize: %d\n", vq->n_sv, vq->vqsize); for (s = 0; s < vq->n_sv; s++) { E_INFO("SV %d feature dims(%d): ", s, vq->gautbl[s].veclen); for (c = 0; c < vq->gautbl[s].veclen; c++) fprintf (stderr, " %2d", vq->featdim[s][c]); fprintf (stderr, "\n"); } fflush (stderr); /* Read VQ codebooks and maps for each subvector */ for (s = 0; s < n_sv; s++) { E_INFO("Reading subvq %d%s\n", s, (s < vq->n_sv) ? "" : " (not used)"); E_INFO("Reading codebook\n"); if ((fgets (line, sizeof(line), fp) == NULL) || (sscanf (line, "Codebook %d", &k) != 1) || (k != s)) E_FATAL("Error reading codebook header\n", s); for (r = 0; r < vq->vqsize; r++) { if (fgets (line, sizeof(line), fp) == NULL) E_FATAL("Error reading row(%d)\n", r); if (s >= vq->n_sv) continue; for (strp = line, c = 0; c < vq->gautbl[s].veclen; c++) { if (sscanf (strp, "%f %f%n", &(vq->gautbl[s].mean[r][c]), &(vq->gautbl[s].var[r][c]), &k) != 2) E_FATAL("Error reading row(%d) col(%d)\n", r, c); strp += k; } } E_INFO("Reading map\n"); if ((fgets (line, sizeof(line), fp) == NULL) || (sscanf (line, "Map %d", &k) != 1) || (k != s)) E_FATAL("Error reading map header\n", s); for (r = 0; r < vq->origsize.r; r++) { if (fgets (line, sizeof(line), fp) == NULL) E_FATAL("Error reading row(%d)\n", r); if (s >= vq->n_sv) continue; for (strp = line, c = 0; c < vq->origsize.c; c++) { if (sscanf (strp, "%d%n", &(vq->map[r][c][s]), &k) != 1) E_FATAL("Error reading row(%d) col(%d)\n", r, c); strp += k; } } fflush (stdout); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -