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++)
143 gauden_dump_ind(g, 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((mfcc_t ****)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;
558 &g->
featlen, cmd_ln_str_r(config,
"-mean"));
559 g->
mean = (mfcc_t ****)fgau;
561 gauden_param_read(&fgau, &m, &f, &d, &flen, cmd_ln_str_r(config,
"-var"));
562 g->
var = (mfcc_t ****)fgau;
567 (
"Mixture-gaussians dimensions for means and variances differ\n");
568 for (i = 0; i < g->
n_feat; i++)
570 E_FATAL(
"Feature lengths for means and variances differ\n");
574 for (i = 0; i < g->
n_mgau; ++i) {
575 for (f = 0; f < g->
n_feat; ++f) {
577 temp = (float64 *) ckd_calloc(g->
featlen[f],
sizeof(float64));
581 for (l = 0; l < g->
featlen[f]; l++) {
583 for (m = 0; m < g->
featlen[f]; m++) {
585 temp[l] += mllr->
A[f][0][l][m] * g->
mean[i][f][d][m];
587 temp[l] += mllr->
b[f][0][l];
590 for (l = 0; l < g->
featlen[f]; l++) {
591 g->
mean[i][f][d][l] = (float32) temp[l];
592 g->
var[i][f][d][l] *= mllr->
h[f][0][l];
601 gauden_dist_precompute(g, g->
lmath, cmd_ln_float32_r(config,
"-varfloor"));