122 #include <sphinxbase/bio.h> 123 #include <sphinxbase/err.h> 124 #include <sphinxbase/ckd_alloc.h> 129 #define GAUDEN_PARAM_VERSION "1.0" 132 #define M_PI 3.1415926535897932385e0 135 #define WORST_DIST (int32)(0x80000000) 142 for (c = 0; c < g->
n_mgau; c++)
152 for (f = 0; f < g->
n_feat; f++) {
153 E_INFO(
"Codebook %d, Feature %d (%dx%d):\n",
158 for (i = 0; i < g->
featlen[f]; i++)
159 printf(
" %7.4f", MFCC2FLOAT(g->
mean[senidx][f][d][i]));
166 for (i = 0; i < g->
featlen[f]; i++)
167 printf(
" %d", (
int)g->
var[senidx][f][d][i]);
173 printf(
"d[%3d] %d\n", d, (
int)g->
det[senidx][f][d]);
179 gauden_param_read(float32 ***** out_param,
182 int32 * out_n_density,
183 int32 ** out_veclen,
const char *file_name)
187 int32 i, j, k, l, n, blk;
192 int32 byteswap, chksum_present;
195 char **argname, **argval;
198 E_INFO(
"Reading mixture gaussian parameter: %s\n", file_name);
200 if ((fp = fopen(file_name,
"rb")) == NULL)
201 E_FATAL_SYSTEM(
"Failed to open file '%s' for reading", file_name);
204 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
205 E_FATAL(
"Failed to read header from file '%s'\n", file_name);
209 for (i = 0; argname[i]; i++) {
210 if (strcmp(argname[i],
"version") == 0) {
211 if (strcmp(argval[i], GAUDEN_PARAM_VERSION) != 0)
212 E_WARN(
"Version mismatch(%s): %s, expecting %s\n",
213 file_name, argval[i], GAUDEN_PARAM_VERSION);
215 else if (strcmp(argname[i],
"chksum0") == 0) {
219 bio_hdrarg_free(argname, argval);
220 argname = argval = NULL;
225 if (bio_fread(&n_mgau,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
226 E_FATAL(
"fread(%s) (#codebooks) failed\n", file_name);
227 *out_n_mgau = n_mgau;
230 if (bio_fread(&n_feat,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
231 E_FATAL(
"fread(%s) (#features) failed\n", file_name);
232 *out_n_feat = n_feat;
235 if (bio_fread(&n_density,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
236 E_FATAL(
"fread(%s) (#density/codebook) failed\n", file_name);
237 *out_n_density = n_density;
240 veclen = ckd_calloc(n_feat,
sizeof(uint32));
241 *out_veclen = veclen;
242 if (bio_fread(veclen,
sizeof(int32), n_feat, fp, byteswap, &chksum) !=
244 E_FATAL(
"fread(%s) (feature-lengths) failed\n", file_name);
247 for (i = 0, blk = 0; i < n_feat; i++)
251 if (bio_fread(&n,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
252 E_FATAL(
"fread(%s) (total #floats) failed\n", file_name);
253 if (n != n_mgau * n_density * blk) {
255 (
"%s: #mfcc_ts(%d) doesn't match dimensions: %d x %d x %d\n",
256 file_name, n, n_mgau, n_density, blk);
261 out = (float32 ****) ckd_calloc_3d(n_mgau, n_feat, n_density,
263 buf = (float32 *) ckd_calloc(n,
sizeof(float32));
264 for (i = 0, l = 0; i < n_mgau; i++) {
265 for (j = 0; j < n_feat; j++) {
266 for (k = 0; k < n_density; k++) {
267 out[i][j][k] = &buf[l];
274 out = (float32 ****) *out_param;
279 if (bio_fread(buf,
sizeof(float32), n, fp, byteswap, &chksum) != n)
280 E_FATAL(
"fread(%s) (densitydata) failed\n", file_name);
283 bio_verify_chksum(fp, byteswap, chksum);
285 if (fread(&tmp, 1, 1, fp) == 1)
286 E_FATAL(
"More data than expected in %s\n", file_name);
292 E_INFO(
"%d codebook, %d feature, size: \n", n_mgau, n_feat);
293 for (i = 0; i < n_feat; i++)
294 E_INFO(
" %dx%d\n", n_density, veclen[i]);
300 gauden_param_free(mfcc_t **** p)
302 ckd_free(p[0][0][0]);
313 gauden_dist_precompute(
gauden_t * g, logmath_t *lmath, float32 varfloor)
315 int32 i, m, f, d, flen;
325 for (m = 0; m < g->
n_mgau; m++) {
326 for (f = 0; f < g->
n_feat; f++) {
330 for (d = 0, detp = g->
det[m][f]; d < g->n_density; d++, detp++) {
332 for (i = 0, varp = g->
var[m][f][d], meanp = g->
mean[m][f][d];
333 i < flen; i++, varp++, meanp++) {
334 float32 *fvarp = (float32 *)varp;
337 float32 *fmp = (float32 *)meanp;
338 *meanp = FLOAT2MFCC(*fmp);
340 if (*fvarp < varfloor) {
344 *detp += (mfcc_t)logmath_log(lmath,
345 1.0 / sqrt(*fvarp * 2.0 * M_PI));
347 *varp = (mfcc_t)logmath_ln_to_log(lmath,
348 (1.0 / (*fvarp * 2.0)));
354 E_INFO(
"%d variance values floored\n", floored);
361 gauden_init(
char const *meanfile,
char const *varfile, float32 varfloor, logmath_t *lmath)
363 int32 i, m, f, d, *flen;
367 assert(meanfile != NULL);
368 assert(varfile != NULL);
369 assert(varfloor > 0.0);
378 g->
mean = (mfcc_t ****)fgau;
380 gauden_param_read(&fgau, &m, &f, &d, &flen, varfile);
381 g->
var = (mfcc_t ****)fgau;
386 (
"Mixture-gaussians dimensions for means and variances differ\n");
387 for (i = 0; i < g->
n_feat; i++)
389 E_FATAL(
"Feature lengths for means and variances differ\n");
393 gauden_dist_precompute(g, lmath, varfloor);
404 gauden_param_free(g->
mean);
406 gauden_param_free(g->
var);
416 compute_dist_all(
gauden_dist_t * out_dist, mfcc_t* obs, int32 featlen,
417 mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
422 for (d = 0; d < n_density; ++d) {
431 for (i = 0; i < featlen; i++) {
436 diff = obs[i] - m[i];
437 dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
443 diff = obs[i] - m[i];
446 dval -= diff * diff * v[i];
450 out_dist[d].
dist = dval;
464 mfcc_t * obs, int32 featlen,
465 mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
472 if (n_top >= n_density)
473 return (compute_dist_all
474 (out_dist, obs, featlen, mean, var, det, n_density));
476 for (i = 0; i < n_top; i++)
477 out_dist[i].dist = WORST_DIST;
478 worst = &(out_dist[n_top - 1]);
480 for (d = 0; d < n_density; d++) {
489 for (i = 0; (i < featlen) && (dval >= worst->
dist); i++) {
494 diff = obs[i] - m[i];
495 dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
501 diff = obs[i] - m[i];
504 dval -= diff * diff * v[i];
508 if ((i < featlen) || (dval < worst->dist))
512 for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++);
514 for (j = n_top - 1; j > i; --j)
515 out_dist[j] = out_dist[j - 1];
516 out_dist[i].
dist = dval;
531 int mgau, int32 n_top, mfcc_t** obs,
gauden_dist_t ** out_dist)
535 assert((n_top > 0) && (n_top <= g->n_density));
537 for (f = 0; f < g->
n_feat; f++) {
538 compute_dist(out_dist[f], n_top,
540 g->
mean[mgau][f], g->
var[mgau][f], g->
det[mgau][f],
542 E_DEBUG(3, (
"Top CW(%d,%d) = %d %d\n", mgau, f, out_dist[f][0].
id,
552 int32 i, m, f, d, *flen;
557 gauden_param_free(g->
mean);
559 gauden_param_free(g->
var);
572 &g->
featlen, cmd_ln_str_r(config,
"-mean"));
573 g->
mean = (mfcc_t ****)fgau;
575 gauden_param_read(&fgau, &m, &f, &d, &flen, cmd_ln_str_r(config,
"-var"));
576 g->
var = (mfcc_t ****)fgau;
581 (
"Mixture-gaussians dimensions for means and variances differ\n");
582 for (i = 0; i < g->
n_feat; i++)
584 E_FATAL(
"Feature lengths for means and variances differ\n");
588 for (i = 0; i < g->
n_mgau; ++i) {
589 for (f = 0; f < g->
n_feat; ++f) {
591 temp = (float64 *) ckd_calloc(g->
featlen[f],
sizeof(float64));
595 for (l = 0; l < g->
featlen[f]; l++) {
597 for (m = 0; m < g->
featlen[f]; m++) {
599 temp[l] += mllr->
A[f][0][l][m] * g->
mean[i][f][d][m];
601 temp[l] += mllr->
b[f][0][l];
604 for (l = 0; l < g->
featlen[f]; l++) {
605 g->
mean[i][f][d][l] = (float32) temp[l];
606 g->
var[i][f][d][l] *= mllr->
h[f][0][l];
615 gauden_dist_precompute(g, g->
lmath, cmd_ln_float32_r(config,
"-varfloor"));
void gauden_dump(const gauden_t *g)
Dump the definitionn of Gaussian distribution.
logmath_t * lmath
log math computation
int32 n_density
Number gaussian densities in each codebook-feature stream.
void gauden_free(gauden_t *g)
Release memory allocated by gauden_init.
int32 id
Index of codeword (gaussian density)
mfcc_t *** det
log(determinant) for each variance vector; actually, log(sqrt(2*pi*det))
Structure to store distance (density) values for a given input observation wrt density values in some...
float32 *** h
Diagonal transformation of variances.
int32 gauden_mllr_transform(gauden_t *s, ps_mllr_t *mllr, cmd_ln_t *config)
Transform Gaussians according to an MLLR matrix (or, eventually, more).
float32 *** b
Bias part of mean transformations.
gauden_t * gauden_init(char const *meanfile, char const *varfile, float32 varfloor, logmath_t *lmath)
Read mixture gaussian codebooks from the given files.
#define WORST_SCORE
Large "bad" score.
int32 * featlen
feature length for each feature
int32 n_mgau
Number codebooks.
(Sphinx 3.0 specific) Gaussian density module.
Feature space linear transform structure.
float32 **** A
Rotation part of mean transformations.
#define SENSCR_SHIFT
Shift count for senone scores.
mfcc_t **** mean
mean[codebook][feature][codeword] vector
int32 n_feat
Number feature streams in each codebook.
mfcc_t dist
Density value for input observation wrt above codeword; NOTE: result in logs3 domain, but var_t used for speed.
void gauden_dump_ind(const gauden_t *g, int senidx)
Dump the definition of Gaussian distribution of a particular index to the standard output stream...
Multivariate gaussian mixture density parameters.
int32 gauden_dist(gauden_t *g, int mgau, int n_top, mfcc_t **obs, gauden_dist_t **out_dist)
Compute gaussian density values for the given input observation vector wrt the specified mixture gaus...
mfcc_t **** var
like mean; diagonal covariance vector only