diff options
Diffstat (limited to 'media/pocketsphinx/src/ms_gauden.c')
-rw-r--r-- | media/pocketsphinx/src/ms_gauden.c | 617 |
1 files changed, 0 insertions, 617 deletions
diff --git a/media/pocketsphinx/src/ms_gauden.c b/media/pocketsphinx/src/ms_gauden.c deleted file mode 100644 index 7c35274801..0000000000 --- a/media/pocketsphinx/src/ms_gauden.c +++ /dev/null @@ -1,617 +0,0 @@ -/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* ==================================================================== - * 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. - * - * ==================================================================== - * - */ -/* - * gauden.c -- gaussian density module. - * - *********************************************** - * CMU ARPA Speech Project - * - * Copyright (c) 1996 Carnegie Mellon University. - * ALL RIGHTS RESERVED. - *********************************************** - * - * HISTORY - * $Log$ - * Revision 1.7 2006/02/22 17:09:55 arthchan2003 - * Merged from SPHINX3_5_2_RCI_IRII_BRANCH: 1, Followed Dave's change, keep active to be uint8 instead int8 in gauden_dist_norm.\n 2, Introdued gauden_dump and gauden_dump_ind. This allows debugging of ms_gauden routine. \n 3, Introduced gauden_free, this fixed some minor memory leaks. \n 4, gauden_init accept an argument precompute to specify whether the distance is pre-computed or not.\n 5, Added license. \n 6, Fixed dox-doc. - * - * - * Revision 1.5.4.7 2006/01/16 19:45:59 arthchan2003 - * Change the gaussian density dumping routine to a function. - * - * Revision 1.5.4.6 2005/10/09 19:51:05 arthchan2003 - * Followed Dave's changed in the trunk. - * - * Revision 1.5.4.5 2005/09/25 18:54:20 arthchan2003 - * Added a flag to turn on and off precomputation. - * - * Revision 1.6 2005/10/05 00:31:14 dhdfu - * Make int8 be explicitly signed (signedness of 'char' is - * architecture-dependent). Then make a bunch of things use uint8 where - * signedness is unimportant, because on the architecture where 'char' is - * unsigned, it is that way for a reason (signed chars are slower). - * - * Revision 1.5.4.4 2005/09/07 23:29:07 arthchan2003 - * Added FIXME warning. - * - * Revision 1.5.4.3 2005/09/07 23:25:10 arthchan2003 - * 1, Behavior changes of cont_mgau, instead of remove Gaussian with zero variance vector before flooring, now remove Gaussian with zero mean and variance before flooring. Notice that this is not yet synchronize with ms_mgau. 2, Added warning message in multi-stream gaussian distribution. - * - * Revision 1.5.4.2 2005/08/03 18:53:44 dhdfu - * Add memory deallocation functions. Also move all the initialization - * of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it - * from decode_anytopo and friends. - * - * Revision 1.5.4.1 2005/07/20 19:39:01 arthchan2003 - * Added licences in ms_* series of code. - * - * Revision 1.5 2005/06/21 18:55:09 arthchan2003 - * 1, Add comments to describe this modules, 2, Fixed doxygen documentation. 3, Added $ keyword. - * - * Revision 1.3 2005/03/30 01:22:47 archan - * Fixed mistakes in last updates. Add - * - * - * 20-Dec-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Changed gauden_param_read to use the new libio/bio_fread functions. - * - * 26-Sep-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Added gauden_mean_reload() for application of MLLR; and correspondingly - * made gauden_param_read allocate memory for parameter only if not - * already allocated. - * - * 09-Sep-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Interleaved two density computations for speed improvement. - * - * 19-Aug-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Added compute_dist_all special case for improving speed. - * - * 26-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Added check for underflow and floor insertion in gauden_dist. - * - * 20-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Added active argument to gauden_dist_norm and gauden_dist_norm_global, - * and made the latter a static function. - * - * 07-Nov-95 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University. - * Initial version created. - * Very liberally borrowed/adapted from Eric's S3 trainer implementation. - */ - -/* System headers. */ -#include <assert.h> -#include <string.h> -#include <math.h> -#include <float.h> - -/* SphinxBase headers. */ -#include <sphinxbase/bio.h> -#include <sphinxbase/err.h> -#include <sphinxbase/ckd_alloc.h> - -/* Local headesr. */ -#include "ms_gauden.h" - -#define GAUDEN_PARAM_VERSION "1.0" - -#ifndef M_PI -#define M_PI 3.1415926535897932385e0 -#endif - -#define WORST_DIST (int32)(0x80000000) - -void -gauden_dump(const gauden_t * g) -{ - int32 c; - - for (c = 0; c < g->n_mgau; c++) - gauden_dump_ind(g, c); -} - - -void -gauden_dump_ind(const gauden_t * g, int senidx) -{ - int32 f, d, i; - - for (f = 0; f < g->n_feat; f++) { - E_INFO("Codebook %d, Feature %d (%dx%d):\n", - senidx, f, g->n_density, g->featlen[f]); - - for (d = 0; d < g->n_density; d++) { - printf("m[%3d]", d); - for (i = 0; i < g->featlen[f]; i++) - printf(" %7.4f", MFCC2FLOAT(g->mean[senidx][f][d][i])); - printf("\n"); - } - printf("\n"); - - for (d = 0; d < g->n_density; d++) { - printf("v[%3d]", d); - for (i = 0; i < g->featlen[f]; i++) - printf(" %d", (int)g->var[senidx][f][d][i]); - printf("\n"); - } - printf("\n"); - - for (d = 0; d < g->n_density; d++) - printf("d[%3d] %d\n", d, (int)g->det[senidx][f][d]); - } - fflush(stderr); -} - -static int32 -gauden_param_read(float32 ***** out_param, /* Alloc space iff *out_param == NULL */ - int32 * out_n_mgau, - int32 * out_n_feat, - int32 * out_n_density, - int32 ** out_veclen, const char *file_name) -{ - char tmp; - FILE *fp; - int32 i, j, k, l, n, blk; - int32 n_mgau; - int32 n_feat; - int32 n_density; - int32 *veclen; - int32 byteswap, chksum_present; - float32 ****out; - float32 *buf; - char **argname, **argval; - uint32 chksum; - - E_INFO("Reading mixture gaussian parameter: %s\n", file_name); - - if ((fp = fopen(file_name, "rb")) == NULL) - E_FATAL_SYSTEM("Failed to open file '%s' for reading", file_name); - - /* Read header, including argument-value info and 32-bit byteorder magic */ - if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0) - E_FATAL("Failed to read header from file '%s'\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], GAUDEN_PARAM_VERSION) != 0) - E_WARN("Version mismatch(%s): %s, expecting %s\n", - file_name, argval[i], GAUDEN_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); - *out_n_mgau = 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); - *out_n_feat = 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); - *out_n_density = n_density; - - /* #Dimensions in each feature stream */ - veclen = ckd_calloc(n_feat, sizeof(uint32)); - *out_veclen = veclen; - if (bio_fread(veclen, sizeof(int32), n_feat, fp, byteswap, &chksum) != - n_feat) - E_FATAL("fread(%s) (feature-lengths) failed\n", file_name); - - /* blk = total vector length of all feature streams */ - for (i = 0, blk = 0; i < n_feat; 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: #mfcc_ts(%d) doesn't match dimensions: %d x %d x %d\n", - file_name, n, n_mgau, n_density, blk); - } - - /* Allocate memory for mixture gaussian densities if not already allocated */ - if (!(*out_param)) { - out = (float32 ****) ckd_calloc_3d(n_mgau, n_feat, n_density, - sizeof(float32 *)); - buf = (float32 *) ckd_calloc(n, sizeof(float32)); - for (i = 0, l = 0; i < n_mgau; i++) { - for (j = 0; j < n_feat; j++) { - for (k = 0; k < n_density; k++) { - out[i][j][k] = &buf[l]; - l += veclen[j]; - } - } - } - } - else { - out = (float32 ****) *out_param; - buf = out[0][0][0]; - } - - /* Read mixture gaussian densities data */ - if (bio_fread(buf, sizeof(float32), n, fp, byteswap, &chksum) != n) - E_FATAL("fread(%s) (densitydata) failed\n", file_name); - - if (chksum_present) - bio_verify_chksum(fp, byteswap, chksum); - - if (fread(&tmp, 1, 1, fp) == 1) - E_FATAL("More data than expected in %s\n", file_name); - - fclose(fp); - - *out_param = out; - - E_INFO("%d codebook, %d feature, size: \n", n_mgau, n_feat); - for (i = 0; i < n_feat; i++) - E_INFO(" %dx%d\n", n_density, veclen[i]); - - return 0; -} - -static void -gauden_param_free(mfcc_t **** p) -{ - ckd_free(p[0][0][0]); - ckd_free_3d(p); -} - -/* - * Some of the gaussian density computation can be carried out in advance: - * log(determinant) calculation, - * 1/(2*var) in the exponent, - * NOTE; The density computation is performed in log domain. - */ -static int32 -gauden_dist_precompute(gauden_t * g, logmath_t *lmath, float32 varfloor) -{ - int32 i, m, f, d, flen; - mfcc_t *meanp; - mfcc_t *varp; - mfcc_t *detp; - int32 floored; - - floored = 0; - /* Allocate space for determinants */ - g->det = ckd_calloc_3d(g->n_mgau, g->n_feat, g->n_density, sizeof(***g->det)); - - for (m = 0; m < g->n_mgau; m++) { - for (f = 0; f < g->n_feat; f++) { - flen = g->featlen[f]; - - /* Determinants for all variance vectors in g->[m][f] */ - for (d = 0, detp = g->det[m][f]; d < g->n_density; d++, detp++) { - *detp = 0; - for (i = 0, varp = g->var[m][f][d], meanp = g->mean[m][f][d]; - i < flen; i++, varp++, meanp++) { - float32 *fvarp = (float32 *)varp; - -#ifdef FIXED_POINT - float32 *fmp = (float32 *)meanp; - *meanp = FLOAT2MFCC(*fmp); -#endif - if (*fvarp < varfloor) { - *fvarp = varfloor; - ++floored; - } - *detp += (mfcc_t)logmath_log(lmath, - 1.0 / sqrt(*fvarp * 2.0 * M_PI)); - /* Precompute this part of the exponential */ - *varp = (mfcc_t)logmath_ln_to_log(lmath, - (1.0 / (*fvarp * 2.0))); - } - } - } - } - - E_INFO("%d variance values floored\n", floored); - - return 0; -} - - -gauden_t * -gauden_init(char const *meanfile, char const *varfile, float32 varfloor, logmath_t *lmath) -{ - int32 i, m, f, d, *flen; - float32 ****fgau; - gauden_t *g; - - assert(meanfile != NULL); - assert(varfile != NULL); - assert(varfloor > 0.0); - - g = (gauden_t *) ckd_calloc(1, sizeof(gauden_t)); - g->lmath = lmath; - - /* Read means and (diagonal) variances for all mixture gaussians */ - fgau = NULL; - gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density, - &g->featlen, meanfile); - g->mean = (mfcc_t ****)fgau; - fgau = NULL; - gauden_param_read(&fgau, &m, &f, &d, &flen, varfile); - g->var = (mfcc_t ****)fgau; - - /* Verify mean and variance parameter dimensions */ - if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density)) - E_FATAL - ("Mixture-gaussians dimensions for means and variances differ\n"); - for (i = 0; i < g->n_feat; i++) - if (g->featlen[i] != flen[i]) - E_FATAL("Feature lengths for means and variances differ\n"); - ckd_free(flen); - - /* Floor variances and precompute variance determinants */ - gauden_dist_precompute(g, lmath, varfloor); - - return g; -} - -void -gauden_free(gauden_t * g) -{ - if (g == NULL) - return; - if (g->mean) - gauden_param_free(g->mean); - if (g->var) - gauden_param_free(g->var); - if (g->det) - ckd_free_3d(g->det); - if (g->featlen) - ckd_free(g->featlen); - ckd_free(g); -} - -/* 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; -} - - -/* - * 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; -} - - -/* - * Compute distances of the input observation from the top N codewords in the given - * codebook (g->{mean,var}[mgau]). The input observation, obs, includes vectors for - * all features in the codebook. - */ -int32 -gauden_dist(gauden_t * g, - int mgau, int32 n_top, mfcc_t** obs, gauden_dist_t ** out_dist) -{ - int32 f; - - assert((n_top > 0) && (n_top <= g->n_density)); - - for (f = 0; f < g->n_feat; f++) { - compute_dist(out_dist[f], n_top, - obs[f], g->featlen[f], - g->mean[mgau][f], g->var[mgau][f], g->det[mgau][f], - g->n_density); - E_DEBUG(3, ("Top CW(%d,%d) = %d %d\n", mgau, f, out_dist[f][0].id, - (int)out_dist[f][0].dist >> SENSCR_SHIFT)); - } - - return 0; -} - -int32 -gauden_mllr_transform(gauden_t *g, ps_mllr_t *mllr, cmd_ln_t *config) -{ - int32 i, m, f, d, *flen; - float32 ****fgau; - - /* Free data if already here */ - if (g->mean) - gauden_param_free(g->mean); - if (g->var) - gauden_param_free(g->var); - if (g->det) - ckd_free_3d(g->det); - if (g->featlen) - ckd_free(g->featlen); - g->mean = NULL; - g->var = NULL; - g->det = NULL; - g->featlen = NULL; - - /* Reload means and variances (un-precomputed). */ - fgau = NULL; - gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density, - &g->featlen, cmd_ln_str_r(config, "-mean")); - g->mean = (mfcc_t ****)fgau; - fgau = NULL; - gauden_param_read(&fgau, &m, &f, &d, &flen, cmd_ln_str_r(config, "-var")); - g->var = (mfcc_t ****)fgau; - - /* Verify mean and variance parameter dimensions */ - if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density)) - E_FATAL - ("Mixture-gaussians dimensions for means and variances differ\n"); - for (i = 0; i < g->n_feat; i++) - if (g->featlen[i] != flen[i]) - E_FATAL("Feature lengths for means and variances differ\n"); - ckd_free(flen); - - /* Transform codebook for each stream s */ - for (i = 0; i < g->n_mgau; ++i) { - for (f = 0; f < g->n_feat; ++f) { - float64 *temp; - temp = (float64 *) ckd_calloc(g->featlen[f], sizeof(float64)); - /* Transform each density d in selected codebook */ - for (d = 0; d < g->n_density; d++) { - int l; - for (l = 0; l < g->featlen[f]; l++) { - temp[l] = 0.0; - for (m = 0; m < g->featlen[f]; m++) { - /* FIXME: For now, only one class, hence the zeros below. */ - temp[l] += mllr->A[f][0][l][m] * g->mean[i][f][d][m]; - } - temp[l] += mllr->b[f][0][l]; - } - - for (l = 0; l < g->featlen[f]; l++) { - g->mean[i][f][d][l] = (float32) temp[l]; - g->var[i][f][d][l] *= mllr->h[f][0][l]; - } - } - ckd_free(temp); - } - } - - /* Re-precompute (if we aren't adapting variances this isn't - * actually necessary...) */ - gauden_dist_precompute(g, g->lmath, cmd_ln_float32_r(config, "-varfloor")); - return 0; -} |