• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

src/libpocketsphinx/ms_gauden.c

00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  */
00037 /*
00038  * gauden.c -- gaussian density module.
00039  *
00040  ***********************************************
00041  * CMU ARPA Speech Project
00042  *
00043  * Copyright (c) 1996 Carnegie Mellon University.
00044  * ALL RIGHTS RESERVED.
00045  ***********************************************
00046  *
00047  * HISTORY
00048  * $Log$
00049  * Revision 1.7  2006/02/22  17:09:55  arthchan2003
00050  * 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.
00051  * 
00052  *
00053  * Revision 1.5.4.7  2006/01/16 19:45:59  arthchan2003
00054  * Change the gaussian density dumping routine to a function.
00055  *
00056  * Revision 1.5.4.6  2005/10/09 19:51:05  arthchan2003
00057  * Followed Dave's changed in the trunk.
00058  *
00059  * Revision 1.5.4.5  2005/09/25 18:54:20  arthchan2003
00060  * Added a flag to turn on and off precomputation.
00061  *
00062  * Revision 1.6  2005/10/05 00:31:14  dhdfu
00063  * Make int8 be explicitly signed (signedness of 'char' is
00064  * architecture-dependent).  Then make a bunch of things use uint8 where
00065  * signedness is unimportant, because on the architecture where 'char' is
00066  * unsigned, it is that way for a reason (signed chars are slower).
00067  *
00068  * Revision 1.5.4.4  2005/09/07 23:29:07  arthchan2003
00069  * Added FIXME warning.
00070  *
00071  * Revision 1.5.4.3  2005/09/07 23:25:10  arthchan2003
00072  * 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.
00073  *
00074  * Revision 1.5.4.2  2005/08/03 18:53:44  dhdfu
00075  * Add memory deallocation functions.  Also move all the initialization
00076  * of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it
00077  * from decode_anytopo and friends.
00078  *
00079  * Revision 1.5.4.1  2005/07/20 19:39:01  arthchan2003
00080  * Added licences in ms_* series of code.
00081  *
00082  * Revision 1.5  2005/06/21 18:55:09  arthchan2003
00083  * 1, Add comments to describe this modules, 2, Fixed doxygen documentation. 3, Added $ keyword.
00084  *
00085  * Revision 1.3  2005/03/30 01:22:47  archan
00086  * Fixed mistakes in last updates. Add
00087  *
00088  * 
00089  * 20-Dec-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00090  *              Changed gauden_param_read to use the new libio/bio_fread functions.
00091  * 
00092  * 26-Sep-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00093  *              Added gauden_mean_reload() for application of MLLR; and correspondingly
00094  *              made gauden_param_read allocate memory for parameter only if not
00095  *              already allocated.
00096  * 
00097  * 09-Sep-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00098  *              Interleaved two density computations for speed improvement.
00099  * 
00100  * 19-Aug-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00101  *              Added compute_dist_all special case for improving speed.
00102  * 
00103  * 26-Jan-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00104  *              Added check for underflow and floor insertion in gauden_dist.
00105  * 
00106  * 20-Jan-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00107  *              Added active argument to gauden_dist_norm and gauden_dist_norm_global,
00108  *              and made the latter a static function.
00109  * 
00110  * 07-Nov-95    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
00111  *              Initial version created.
00112  *              Very liberally borrowed/adapted from Eric's S3 trainer implementation.
00113  */
00114 
00115 /* System headers. */
00116 #include <assert.h>
00117 #include <string.h>
00118 #include <math.h>
00119 #include <float.h>
00120 
00121 /* SphinxBase headers. */
00122 #include <bio.h>
00123 #include <err.h>
00124 #include <ckd_alloc.h>
00125 
00126 /* Local headesr. */
00127 #include "ms_gauden.h"
00128 
00129 #define GAUDEN_PARAM_VERSION    "1.0"
00130 
00131 #ifndef M_PI
00132 #define M_PI    3.1415926535897932385e0
00133 #endif
00134 
00135 #define WORST_DIST      (int32)(0x80000000)
00136 
00137 void
00138 gauden_dump(const gauden_t * g)
00139 {
00140     int32 c;
00141 
00142     for (c = 0; c < g->n_mgau; c++)
00143         gauden_dump_ind(g, c);
00144 }
00145 
00146 
00147 void
00148 gauden_dump_ind(const gauden_t * g, int senidx)
00149 {
00150     int32 f, d, i;
00151 
00152     for (f = 0; f < g->n_feat; f++) {
00153         E_INFO("Codebook %d, Feature %d (%dx%d):\n",
00154                senidx, f, g->n_density, g->featlen[f]);
00155 
00156         for (d = 0; d < g->n_density; d++) {
00157             printf("m[%3d]", d);
00158             for (i = 0; i < g->featlen[f]; i++)
00159                 printf(" %7.4f", MFCC2FLOAT(g->mean[senidx][f][d][i]));
00160             printf("\n");
00161         }
00162         printf("\n");
00163 
00164         for (d = 0; d < g->n_density; d++) {
00165             printf("v[%3d]", d);
00166             for (i = 0; i < g->featlen[f]; i++)
00167                 printf(" %d", (int)g->var[senidx][f][d][i]);
00168             printf("\n");
00169         }
00170         printf("\n");
00171 
00172         for (d = 0; d < g->n_density; d++)
00173             printf("d[%3d] %d\n", d, (int)g->det[senidx][f][d]);
00174     }
00175     fflush(stderr);
00176 }
00177 
00178 static int32
00179 gauden_param_read(float32 ***** out_param,      /* Alloc space iff *out_param == NULL */
00180                   int32 * out_n_mgau,
00181                   int32 * out_n_feat,
00182                   int32 * out_n_density,
00183                   int32 ** out_veclen, const char *file_name)
00184 {
00185     char tmp;
00186     FILE *fp;
00187     int32 i, j, k, l, n, blk;
00188     int32 n_mgau;
00189     int32 n_feat;
00190     int32 n_density;
00191     int32 *veclen;
00192     int32 byteswap, chksum_present;
00193     float32 ****out;
00194     float32 *buf;
00195     char **argname, **argval;
00196     uint32 chksum;
00197 
00198     E_INFO("Reading mixture gaussian parameter: %s\n", file_name);
00199 
00200     if ((fp = fopen(file_name, "rb")) == NULL)
00201         E_FATAL_SYSTEM("fopen(%s,rb) failed\n", file_name);
00202 
00203     /* Read header, including argument-value info and 32-bit byteorder magic */
00204     if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
00205         E_FATAL("bio_readhdr(%s) failed\n", file_name);
00206 
00207     /* Parse argument-value list */
00208     chksum_present = 0;
00209     for (i = 0; argname[i]; i++) {
00210         if (strcmp(argname[i], "version") == 0) {
00211             if (strcmp(argval[i], GAUDEN_PARAM_VERSION) != 0)
00212                 E_WARN("Version mismatch(%s): %s, expecting %s\n",
00213                        file_name, argval[i], GAUDEN_PARAM_VERSION);
00214         }
00215         else if (strcmp(argname[i], "chksum0") == 0) {
00216             chksum_present = 1; /* Ignore the associated value */
00217         }
00218     }
00219     bio_hdrarg_free(argname, argval);
00220     argname = argval = NULL;
00221 
00222     chksum = 0;
00223 
00224     /* #Codebooks */
00225     if (bio_fread(&n_mgau, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
00226         E_FATAL("fread(%s) (#codebooks) failed\n", file_name);
00227     *out_n_mgau = n_mgau;
00228 
00229     /* #Features/codebook */
00230     if (bio_fread(&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
00231         E_FATAL("fread(%s) (#features) failed\n", file_name);
00232     *out_n_feat = n_feat;
00233 
00234     /* #Gaussian densities/feature in each codebook */
00235     if (bio_fread(&n_density, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
00236         E_FATAL("fread(%s) (#density/codebook) failed\n", file_name);
00237     *out_n_density = n_density;
00238 
00239     /* #Dimensions in each feature stream */
00240     veclen = ckd_calloc(n_feat, sizeof(uint32));
00241     *out_veclen = veclen;
00242     if (bio_fread(veclen, sizeof(int32), n_feat, fp, byteswap, &chksum) !=
00243         n_feat)
00244         E_FATAL("fread(%s) (feature-lengths) failed\n", file_name);
00245 
00246     /* blk = total vector length of all feature streams */
00247     for (i = 0, blk = 0; i < n_feat; i++)
00248         blk += veclen[i];
00249 
00250     /* #Floats to follow; for the ENTIRE SET of CODEBOOKS */
00251     if (bio_fread(&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
00252         E_FATAL("fread(%s) (total #floats) failed\n", file_name);
00253     if (n != n_mgau * n_density * blk) {
00254         E_FATAL
00255             ("%s: #mfcc_ts(%d) doesn't match dimensions: %d x %d x %d\n",
00256              file_name, n, n_mgau, n_density, blk);
00257     }
00258 
00259     /* Allocate memory for mixture gaussian densities if not already allocated */
00260     if (!(*out_param)) {
00261         out = (float32 ****) ckd_calloc_3d(n_mgau, n_feat, n_density,
00262                                          sizeof(float32 *));
00263         buf = (float32 *) ckd_calloc(n, sizeof(float32));
00264         for (i = 0, l = 0; i < n_mgau; i++) {
00265             for (j = 0; j < n_feat; j++) {
00266                 for (k = 0; k < n_density; k++) {
00267                     out[i][j][k] = &buf[l];
00268                     l += veclen[j];
00269                 }
00270             }
00271         }
00272     }
00273     else {
00274         out = (float32 ****) *out_param;
00275         buf = out[0][0][0];
00276     }
00277 
00278     /* Read mixture gaussian densities data */
00279     if (bio_fread(buf, sizeof(float32), n, fp, byteswap, &chksum) != n)
00280         E_FATAL("fread(%s) (densitydata) failed\n", file_name);
00281 
00282     if (chksum_present)
00283         bio_verify_chksum(fp, byteswap, chksum);
00284 
00285     if (fread(&tmp, 1, 1, fp) == 1)
00286         E_FATAL("More data than expected in %s\n", file_name);
00287 
00288     fclose(fp);
00289 
00290     *out_param = out;
00291 
00292     E_INFO("%d codebook, %d feature, size\n", n_mgau, n_feat);
00293     for (i = 0; i < n_feat; i++)
00294         printf(" %dx%d", n_density, veclen[i]);
00295     printf("\n");
00296     fflush(stdout);
00297 
00298     return 0;
00299 }
00300 
00301 static void
00302 gauden_param_free(mfcc_t **** p)
00303 {
00304     ckd_free(p[0][0][0]);
00305     ckd_free_3d(p);
00306 }
00307 
00308 /*
00309  * Some of the gaussian density computation can be carried out in advance:
00310  *      log(determinant) calculation,
00311  *      1/(2*var) in the exponent,
00312  * NOTE; The density computation is performed in log domain.
00313  */
00314 static int32
00315 gauden_dist_precompute(gauden_t * g, logmath_t *lmath, float32 varfloor)
00316 {
00317     int32 i, m, f, d, flen;
00318     mfcc_t *meanp;
00319     mfcc_t *varp;
00320     mfcc_t *detp;
00321     int32 floored;
00322 
00323     floored = 0;
00324     /* Allocate space for determinants */
00325     g->det = ckd_calloc_3d(g->n_mgau, g->n_feat, g->n_density, sizeof(***g->det));
00326 
00327     for (m = 0; m < g->n_mgau; m++) {
00328         for (f = 0; f < g->n_feat; f++) {
00329             flen = g->featlen[f];
00330 
00331             /* Determinants for all variance vectors in g->[m][f] */
00332             for (d = 0, detp = g->det[m][f]; d < g->n_density; d++, detp++) {
00333                 *detp = 0;
00334                 for (i = 0, varp = g->var[m][f][d], meanp = g->mean[m][f][d];
00335                      i < flen; i++, varp++, meanp++) {
00336                     float32 *fvarp = (float32 *)varp;
00337 
00338 #ifdef FIXED_POINT
00339                     float32 *fmp = (float32 *)meanp;
00340                     *meanp = FLOAT2MFCC(*fmp);
00341 #endif
00342                     if (*fvarp < varfloor) {
00343                         *fvarp = varfloor;
00344                         ++floored;
00345                     }
00346                     *detp += (mfcc_t)logmath_log(lmath,
00347                                                  1.0 / sqrt(*fvarp * 2.0 * M_PI));
00348                     /* Precompute this part of the exponential */
00349                     *varp = (mfcc_t)logmath_ln_to_log(lmath,
00350                                                       (1.0 / (*fvarp * 2.0)));
00351                 }
00352             }
00353         }
00354     }
00355 
00356     E_INFO("%d variance values floored\n", floored);
00357 
00358     return 0;
00359 }
00360 
00361 
00362 gauden_t *
00363 gauden_init(char const *meanfile, char const *varfile, float32 varfloor, logmath_t *lmath)
00364 {
00365     int32 i, m, f, d, *flen;
00366     float32 ****fgau;
00367     gauden_t *g;
00368 
00369     assert(meanfile != NULL);
00370     assert(varfile != NULL);
00371     assert(varfloor > 0.0);
00372 
00373     g = (gauden_t *) ckd_calloc(1, sizeof(gauden_t));
00374     g->lmath = lmath;
00375 
00376     /* Read means and (diagonal) variances for all mixture gaussians */
00377     fgau = NULL;
00378     gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density,
00379                       &g->featlen, meanfile);
00380     g->mean = (mfcc_t ****)fgau;
00381     fgau = NULL;
00382     gauden_param_read(&fgau, &m, &f, &d, &flen, varfile);
00383     g->var = (mfcc_t ****)fgau;
00384 
00385     /* Verify mean and variance parameter dimensions */
00386     if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density))
00387         E_FATAL
00388             ("Mixture-gaussians dimensions for means and variances differ\n");
00389     for (i = 0; i < g->n_feat; i++)
00390         if (g->featlen[i] != flen[i])
00391             E_FATAL("Feature lengths for means and variances differ\n");
00392     ckd_free(flen);
00393 
00394     /* Floor variances and precompute variance determinants */
00395     gauden_dist_precompute(g, lmath, varfloor);
00396 
00397     return g;
00398 }
00399 
00400 void
00401 gauden_free(gauden_t * g)
00402 {
00403     if (g == NULL)
00404         return;
00405     if (g->mean)
00406         gauden_param_free(g->mean);
00407     if (g->var)
00408         gauden_param_free((mfcc_t ****)g->var);
00409     if (g->det)
00410         ckd_free_3d(g->det);
00411     if (g->featlen)
00412         ckd_free(g->featlen);
00413     ckd_free(g);
00414 }
00415 
00416 /* See compute_dist below */
00417 static int32
00418 compute_dist_all(gauden_dist_t * out_dist, mfcc_t* obs, int32 featlen,
00419                  mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
00420                  int32 n_density)
00421 {
00422     int32 i, d;
00423 
00424     for (d = 0; d < n_density; ++d) {
00425         mfcc_t *m;
00426         mfcc_t *v;
00427         mfcc_t dval;
00428 
00429         m = mean[d];
00430         v = var[d];
00431         dval = det[d];
00432 
00433         for (i = 0; i < featlen; i++) {
00434             mfcc_t diff;
00435 #ifdef FIXED_POINT
00436             /* Have to check for underflows here. */
00437             mfcc_t pdval = dval;
00438             diff = obs[i] - m[i];
00439             dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
00440             if (dval > pdval) {
00441                 dval = WORST_SCORE;
00442                 break;
00443             }
00444 #else
00445             diff = obs[i] - m[i];
00446             /* The compiler really likes this to be a single
00447              * expression, for whatever reason. */
00448             dval -= diff * diff * v[i];
00449 #endif
00450         }
00451 
00452         out_dist[d].dist = dval;
00453         out_dist[d].id = d;
00454     }
00455 
00456     return 0;
00457 }
00458 
00459 
00460 /*
00461  * Compute the top-N closest gaussians from the chosen set (mgau,feat)
00462  * for the given input observation vector.
00463  */
00464 static int32
00465 compute_dist(gauden_dist_t * out_dist, int32 n_top,
00466              mfcc_t * obs, int32 featlen,
00467              mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
00468              int32 n_density)
00469 {
00470     int32 i, j, d;
00471     gauden_dist_t *worst;
00472 
00473     /* Special case optimization when n_density <= n_top */
00474     if (n_top >= n_density)
00475         return (compute_dist_all
00476                 (out_dist, obs, featlen, mean, var, det, n_density));
00477 
00478     for (i = 0; i < n_top; i++)
00479         out_dist[i].dist = WORST_DIST;
00480     worst = &(out_dist[n_top - 1]);
00481 
00482     for (d = 0; d < n_density; d++) {
00483         mfcc_t *m;
00484         mfcc_t *v;
00485         mfcc_t dval;
00486 
00487         m = mean[d];
00488         v = var[d];
00489         dval = det[d];
00490 
00491         for (i = 0; (i < featlen) && (dval >= worst->dist); i++) {
00492             mfcc_t diff;
00493 #ifdef FIXED_POINT
00494             /* Have to check for underflows here. */
00495             mfcc_t pdval = dval;
00496             diff = obs[i] - m[i];
00497             dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
00498             if (dval > pdval) {
00499                 dval = WORST_SCORE;
00500                 break;
00501             }
00502 #else
00503             diff = obs[i] - m[i];
00504             /* The compiler really likes this to be a single
00505              * expression, for whatever reason. */
00506             dval -= diff * diff * v[i];
00507 #endif
00508         }
00509 
00510         if ((i < featlen) || (dval < worst->dist))     /* Codeword d worse than worst */
00511             continue;
00512 
00513         /* Codeword d at least as good as worst so far; insert in the ordered list */
00514         for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++);
00515         assert(i < n_top);
00516         for (j = n_top - 1; j > i; --j)
00517             out_dist[j] = out_dist[j - 1];
00518         out_dist[i].dist = dval;
00519         out_dist[i].id = d;
00520     }
00521 
00522     return 0;
00523 }
00524 
00525 
00526 /*
00527  * Compute distances of the input observation from the top N codewords in the given
00528  * codebook (g->{mean,var}[mgau]).  The input observation, obs, includes vectors for
00529  * all features in the codebook.
00530  */
00531 int32
00532 gauden_dist(gauden_t * g,
00533             int mgau, int32 n_top, mfcc_t** obs, gauden_dist_t ** out_dist)
00534 {
00535     int32 f;
00536 
00537     assert((n_top > 0) && (n_top <= g->n_density));
00538 
00539     for (f = 0; f < g->n_feat; f++) {
00540         compute_dist(out_dist[f], n_top,
00541                      obs[f], g->featlen[f],
00542                      g->mean[mgau][f], g->var[mgau][f], g->det[mgau][f],
00543                      g->n_density);
00544         E_DEBUG(3, ("Top CW(%d,%d) = %d %d\n", mgau, f, out_dist[f][0].id,
00545                     (int)out_dist[f][0].dist >> SENSCR_SHIFT));
00546     }
00547 
00548     return 0;
00549 }
00550 
00551 int32
00552 gauden_mllr_transform(gauden_t *g, ps_mllr_t *mllr, cmd_ln_t *config)
00553 {
00554     int32 i, m, f, d, *flen;
00555     float32 ****fgau;
00556 
00557     /* Reload means and variances (un-precomputed). */
00558     fgau = NULL;
00559     gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density,
00560                       &g->featlen, cmd_ln_str_r(config, "-mean"));
00561     g->mean = (mfcc_t ****)fgau;
00562     fgau = NULL;
00563     gauden_param_read(&fgau, &m, &f, &d, &flen, cmd_ln_str_r(config, "-var"));
00564     g->var = (mfcc_t ****)fgau;
00565 
00566     /* Verify mean and variance parameter dimensions */
00567     if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density))
00568         E_FATAL
00569             ("Mixture-gaussians dimensions for means and variances differ\n");
00570     for (i = 0; i < g->n_feat; i++)
00571         if (g->featlen[i] != flen[i])
00572             E_FATAL("Feature lengths for means and variances differ\n");
00573     ckd_free(flen);
00574 
00575     /* Transform codebook for each stream s */
00576     for (i = 0; i < g->n_mgau; ++i) {
00577         for (f = 0; f < g->n_feat; ++f) {
00578             float64 *temp;
00579             temp = (float64 *) ckd_calloc(g->featlen[f], sizeof(float64));
00580             /* Transform each density d in selected codebook */
00581             for (d = 0; d < g->n_density; d++) {
00582                 int l;
00583                 for (l = 0; l < g->featlen[f]; l++) {
00584                     temp[l] = 0.0;
00585                     for (m = 0; m < g->featlen[f]; m++) {
00586                         /* FIXME: For now, only one class, hence the zeros below. */
00587                         temp[l] += mllr->A[f][0][l][m] * g->mean[i][f][d][m];
00588                     }
00589                     temp[l] += mllr->b[f][0][l];
00590                 }
00591 
00592                 for (l = 0; l < g->featlen[f]; l++) {
00593                     g->mean[i][f][d][l] = (float32) temp[l];
00594                     g->var[i][f][d][l] *= mllr->h[f][0][l];
00595                 }
00596             }
00597             ckd_free(temp);
00598         }
00599     }
00600 
00601     /* Re-precompute (if we aren't adapting variances this isn't
00602      * actually necessary...) */
00603     gauden_dist_precompute(g, g->lmath, cmd_ln_float32_r(config, "-varfloor"));
00604     return 0;
00605 }

Generated on Tue Aug 17 2010 for PocketSphinx by  doxygen 1.7.1