📄 s2_semi_mgau.c
字号:
} /* Use the last index to hide a pointer to the entire file's memory */ s->OPDF_8B[s->n_feat] = s2_mmap(file); for (n = 0; n < s->n_feat; n++) { for (i = 0; i < r; i++) { s->OPDF_8B[n][i] = (char *) ((caddr_t) s->OPDF_8B[s->n_feat] + offset); offset += c; } } } else { s->OPDF_8B = (unsigned char ***) ckd_calloc_3d(s->n_feat, r, c, sizeof(unsigned char)); /* Read pdf values and ids */ for (n = 0; n < s->n_feat; n++) { for (i = 0; i < r; i++) { if (fread(s->OPDF_8B[n][i], sizeof(unsigned char), c, fp) != (size_t) c) E_FATAL("fread failed\n"); } } } fclose(fp); return 0;}static voiddump_probs_8b(s2_semi_mgau_t *s, char const *file, /* output file */ char const *dir){ /* **ORIGINAL** HMM directory */ FILE *fp; int32 f, i, k, aligned_c; static char const *title = "V6 Senone Probs, Smoothed, Normalized"; static char const *clust_hdr = "cluster_count 0"; E_INFO("Dumping quantized HMMs to dump file %s\n", file); if ((fp = fopen(file, "wb")) == NULL) { E_ERROR("fopen(%s,wb) failed\n", file); return; }#define fwrite_int32(f,v) fwrite(&v,sizeof(v),1,f) /* Write title size and title (directory name) */ k = strlen(title) + 1; /* including trailing null-char */ fwrite_int32(fp, k); fwrite(title, sizeof(char), k, fp); /* Write header size and header (directory name) */ k = strlen(dir) + 1; /* including trailing null-char */ fwrite_int32(fp, k); fwrite(dir, sizeof(char), k, fp); /* Write cluster count = 0 to indicate this is pre-quantized */ k = strlen(clust_hdr) + 1; fwrite_int32(fp, k); fwrite(clust_hdr, sizeof(char), k, fp); /* Pad it out for alignment purposes */ k = ftell(fp) & 3; if (k > 0) { k = 4 - k; fwrite_int32(fp, k); fwrite("!!!!", 1, 4, fp); } /* Write 0, terminating header strings */ k = 0; fwrite_int32(fp, k); /* Align the number of pdfs to a 4-byte boundary. */ aligned_c = (s->n_density + 3) & ~3; /* Write #rows, #cols; this also indicates whether pdfs already transposed */ fwrite_int32(fp, s->CdWdPDFMod); fwrite_int32(fp, aligned_c); /* Now write out the quantized senones. */ for (f = 0; f < s->n_feat; ++f) { for (i = 0; i < s->CdWdPDFMod; i++) { fwrite(s->OPDF_8B[f][i], sizeof(char), s->n_density, fp); /* Pad them out for alignment purposes */ fwrite("\0\0\0\0", 1, aligned_c - s->n_density, fp); } } fclose(fp);}static int32read_dists_s3(s2_semi_mgau_t * s, char const *file_name, double SmoothMin){ char **argname, **argval; char eofchk; FILE *fp; int32 byteswap, chksum_present; uint32 chksum; float32 *pdf; int32 i, f, c, n; int32 n_sen; int32 n_feat; int32 n_comp; int32 n_err; char *dumpfile; dumpfile = kb_get_senprob_dump_file(); if (dumpfile) { if (load_senone_dists_8bits(s, dumpfile) == 0) return bin_mdef_n_sen(mdef); else E_INFO ("No senone dump file found, will compress mixture weights on-line\n"); } E_INFO("Reading mixture weights file '%s'\n", file_name); if ((fp = fopen(file_name, "rb")) == NULL) E_FATAL("fopen(%s,rb) failed\n", file_name); /* Read header, including argument-value info and 32-bit byteorder magic */ if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0) E_FATAL("bio_readhdr(%s) failed\n", file_name); /* Parse argument-value list */ chksum_present = 0; for (i = 0; argname[i]; i++) { if (strcmp(argname[i], "version") == 0) { if (strcmp(argval[i], MGAU_MIXW_VERSION) != 0) E_WARN("Version mismatch(%s): %s, expecting %s\n", file_name, argval[i], MGAU_MIXW_VERSION); } else if (strcmp(argname[i], "chksum0") == 0) { chksum_present = 1; /* Ignore the associated value */ } } bio_hdrarg_free(argname, argval); argname = argval = NULL; chksum = 0; /* Read #senones, #features, #codewords, arraysize */ if ((bio_fread(&n_sen, sizeof(int32), 1, fp, byteswap, &chksum) != 1) || (bio_fread(&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1) || (bio_fread(&n_comp, sizeof(int32), 1, fp, byteswap, &chksum) != 1) || (bio_fread(&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)) { E_FATAL("bio_fread(%s) (arraysize) failed\n", file_name); } if (n_feat != s->n_feat) E_FATAL("#Features streams(%d) != %d\n", n_feat, s->n_feat); if (n != n_sen * n_feat * n_comp) { E_FATAL ("%s: #float32s(%d) doesn't match header dimensions: %d x %d x %d\n", file_name, i, n_sen, n_feat, n_comp); } /* Quantized mixture weight arrays. */ s->OPDF_8B = (unsigned char ***) ckd_calloc_3d(s->n_feat, s->n_density, n_sen, sizeof(unsigned char)); /* Temporary structure to read in floats before conversion to (int32) logs3 */ pdf = (float32 *) ckd_calloc(n_comp, sizeof(float32)); /* Read senone probs data, normalize, floor, convert to logs3, truncate to 8 bits */ n_err = 0; for (i = 0; i < n_sen; i++) { for (f = 0; f < n_feat; f++) { if (bio_fread((void *) pdf, sizeof(float32), n_comp, fp, byteswap, &chksum) != n_comp) { E_FATAL("bio_fread(%s) (arraydata) failed\n", file_name); } /* Normalize and floor */ if (vector_sum_norm(pdf, n_comp) <= 0.0) n_err++; vector_floor(pdf, n_comp, SmoothMin); vector_sum_norm(pdf, n_comp); /* Convert to LOG, quantize, and transpose */ for (c = 0; c < n_comp; c++) { int32 qscr; qscr = LOG(pdf[c]); /* ** HACK!! ** hardwired threshold!!! */ if (qscr < -161900) E_FATAL("**ERROR** Too low senone PDF value: %d\n", qscr); qscr = (511 - qscr) >> 10; if ((qscr > 255) || (qscr < 0)) E_FATAL("scr(%d,%d,%d) = %d\n", f, c, i, qscr); s->OPDF_8B[f][c][i] = qscr; } } } if (n_err > 0) E_ERROR("Weight normalization failed for %d senones\n", n_err); ckd_free(pdf); if (chksum_present) bio_verify_chksum(fp, byteswap, chksum); if (fread(&eofchk, 1, 1, fp) == 1) E_FATAL("More data than expected in %s\n", file_name); fclose(fp); E_INFO("Read %d x %d x %d mixture weights\n", n_sen, n_feat, n_comp); if ((dumpfile = kb_get_senprob_dump_file()) != NULL) { dump_probs_8b(s, dumpfile, file_name); } return n_sen;}/* Read a Sphinx3 mean or variance file. */static int32s3_read_mgau(s2_semi_mgau_t *s, const char *file_name, float32 ***out_cb){ char tmp; FILE *fp; int32 i, blk, n; int32 n_mgau; int32 n_feat; int32 n_density; int32 *veclen; int32 byteswap, chksum_present; char **argname, **argval; uint32 chksum; E_INFO("Reading S3 mixture gaussian file '%s'\n", file_name); if ((fp = fopen(file_name, "rb")) == NULL) E_FATAL("fopen(%s,rb) failed\n", file_name); /* Read header, including argument-value info and 32-bit byteorder magic */ if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0) E_FATAL("bio_readhdr(%s) failed\n", file_name); /* Parse argument-value list */ chksum_present = 0; for (i = 0; argname[i]; i++) { if (strcmp(argname[i], "version") == 0) { if (strcmp(argval[i], MGAU_PARAM_VERSION) != 0) E_WARN("Version mismatch(%s): %s, expecting %s\n", file_name, argval[i], MGAU_PARAM_VERSION); } else if (strcmp(argname[i], "chksum0") == 0) { chksum_present = 1; /* Ignore the associated value */ } } bio_hdrarg_free(argname, argval); argname = argval = NULL; chksum = 0; /* #Codebooks */ if (bio_fread(&n_mgau, sizeof(int32), 1, fp, byteswap, &chksum) != 1) E_FATAL("fread(%s) (#codebooks) failed\n", file_name); if (n_mgau != 1) E_FATAL("%s: #codebooks (%d) != 1\n", file_name, n_mgau); /* #Features/codebook */ if (bio_fread(&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1) E_FATAL("fread(%s) (#features) failed\n", file_name); if (s->n_feat == 0) s->n_feat = n_feat; else if (n_feat != s->n_feat) E_FATAL("#Features streams(%d) != %d\n", n_feat, s->n_feat); /* #Gaussian densities/feature in each codebook */ if (bio_fread(&n_density, sizeof(int32), 1, fp, byteswap, &chksum) != 1) E_FATAL("fread(%s) (#density/codebook) failed\n", file_name); if (s->n_density == 0) s->n_density = n_density; else if (n_density != s->n_density) E_FATAL("%s: Number of densities per feature(%d) != %d\n", file_name, n_mgau, s->n_density); /* Vector length of feature stream */ if (s->veclen == NULL) s->veclen = ckd_calloc(s->n_feat, sizeof(int32)); veclen = ckd_calloc(s->n_feat, sizeof(int32)); if (bio_fread(veclen, sizeof(int32), s->n_feat, fp, byteswap, &chksum) != s->n_feat) E_FATAL("fread(%s) (feature vector-length) failed\n", file_name); for (i = 0, blk = 0; i < s->n_feat; ++i) { if (s->veclen[i] == 0) s->veclen[i] = veclen[i]; else if (veclen[i] != s->veclen[i]) E_FATAL("feature stream length %d is inconsistent (%d != %d)\n", i, veclen[i], s->veclen[i]); blk += veclen[i]; } /* #Floats to follow; for the ENTIRE SET of CODEBOOKS */ if (bio_fread(&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1) E_FATAL("fread(%s) (total #floats) failed\n", file_name); if (n != n_mgau * n_density * blk) E_FATAL ("%s: #float32s(%d) doesn't match dimensions: %d x %d x %d\n", file_name, n, n_mgau, n_density, blk); *out_cb = ckd_calloc(s->n_feat, sizeof(float32 *)); for (i = 0; i < s->n_feat; ++i) { (*out_cb)[i] = (float32 *) ckd_calloc(n_density * veclen[i], sizeof(float32)); if (bio_fread ((*out_cb)[i], sizeof(float32), n_density * veclen[i], fp, byteswap, &chksum) != n_density * veclen[i]) E_FATAL("fread(%s, %d) of feat %d failed\n", file_name, n_density * veclen[i], i); } ckd_free(veclen); if (chksum_present) bio_verify_chksum(fp, byteswap, chksum); if (fread(&tmp, 1, 1, fp) == 1) E_FATAL("%s: More data than expected\n", file_name); fclose(fp); E_INFO("%d mixture Gaussians, %d components, veclen %d\n", n_mgau, n_density, blk); return n;}static int32s3_precomp(s2_semi_mgau_t *s, float32 vFloor){ int feat; for (feat = 0; feat < s->n_feat; ++feat) { float32 *fmp; mean_t *mp; var_t *vp; int32 *dp, vecLen, i; vecLen = s->veclen[feat]; fmp = (float32 *) s->means[feat]; mp = s->means[feat]; vp = s->vars[feat]; dp = s->dets[feat]; for (i = 0; i < s->n_density; ++i) { int32 d, j; d = 0; for (j = 0; j < vecLen; ++j, ++vp, ++mp, ++fmp) { float64 fvar;#ifdef FIXED_POINT *mp = FLOAT2FIX(*fmp);#endif /* Always do these pre-calculations in floating point */ fvar = *(float32 *) vp; if (fvar < vFloor) fvar = vFloor; d += LOG(1 / sqrt(fvar * 2.0 * PI)); *vp = (var_t) (1.0 / (2.0 * fvar * LOG_BASE)); } *dp++ = d; } } return 0;}s2_semi_mgau_t *s2_semi_mgau_init(const char *mean_path, const char *var_path, float64 varfloor, const char *mixw_path, float64 mixwfloor, int32 topn){ s2_semi_mgau_t *s; int i; s = ckd_calloc(1, sizeof(*s)); /* Read means and variances. */ if (s3_read_mgau(s, mean_path, (float32 ***)&s->means) < 0) { /* FIXME: This actually is not enough to really free everything. */ ckd_free(s); return NULL; } if (s3_read_mgau(s, var_path, (float32 ***)&s->vars) < 0) { /* FIXME: This actually is not enough to really free everything. */ ckd_free(s); return NULL; } /* Precompute (and fixed-point-ize) means, variances, and determinants. */ s->dets = (int32 **)ckd_calloc_2d(s->n_feat, s->n_density, sizeof(int32)); s3_precomp(s, varfloor); /* Read mixture weights (gives us CdWdPDFMod = number of * mixture weights per codeword, which is fixed at the number * of senones since we have only one codebook) */ s->CdWdPDFMod = read_dists_s3(s, mixw_path, mixwfloor); s->topN = topn; s->ds_ratio = 1; /* Top-N scores from current, previous frame */ s->f = (vqFeature_t **) ckd_calloc_2d(s->n_feat, topn, sizeof(vqFeature_t)); s->lastf = (vqFeature_t **) ckd_calloc_2d(s->n_feat, topn, sizeof(vqFeature_t)); for (i = 0; i < s->n_feat; ++i) { int32 j; for (j = 0; j < topn; ++j) { s->lastf[i][j].val.dist = WORST_DIST; s->lastf[i][j].codeword = j; } } /* Temporary array used in senone eval */ s->score_tmp = ckd_calloc(s->n_feat, sizeof(int32)); return s;}voids2_semi_mgau_free(s2_semi_mgau_t * s){ /* FIXME: Need to free stuff. */ ckd_free(s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -