43 #include <sphinxbase/bio.h> 44 #include <sphinxbase/err.h> 45 #include <sphinxbase/ckd_alloc.h> 49 #define GAUDEN_PARAM_VERSION "1.0" 52 #define M_PI 3.1415926535897932385e0 55 #define WORST_DIST (int32)(0x80000000) 62 for (c = 0; c < g->
n_mgau; c++)
72 for (f = 0; f < g->
n_feat; f++) {
73 E_INFO(
"Codebook %d, Feature %d (%dx%d):\n",
78 for (i = 0; i < g->
featlen[f]; i++)
79 printf(
" %7.4f", MFCC2FLOAT(g->
mean[senidx][f][d][i]));
86 for (i = 0; i < g->
featlen[f]; i++)
87 printf(
" %d", (
int)g->
var[senidx][f][d][i]);
93 printf(
"d[%3d] %d\n", d, (
int)g->
det[senidx][f][d]);
108 gauden_param_read(
const char *file_name,
111 int32 * out_n_density,
116 int32 i, j, k, l, n, blk;
121 int32 byteswap, chksum_present;
124 char **argname, **argval;
127 E_INFO(
"Reading mixture gaussian parameter: %s\n", file_name);
129 if ((fp = fopen(file_name,
"rb")) == NULL) {
130 E_ERROR_SYSTEM(
"Failed to open file '%s' for reading", file_name);
135 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0) {
136 E_ERROR(
"Failed to read header from file '%s'\n", file_name);
143 for (i = 0; argname[i]; i++) {
144 if (strcmp(argname[i],
"version") == 0) {
145 if (strcmp(argval[i], GAUDEN_PARAM_VERSION) != 0)
146 E_WARN(
"Version mismatch(%s): %s, expecting %s\n",
147 file_name, argval[i], GAUDEN_PARAM_VERSION);
149 else if (strcmp(argname[i],
"chksum0") == 0) {
153 bio_hdrarg_free(argname, argval);
154 argname = argval = NULL;
159 if (bio_fread(&n_mgau,
sizeof(int32), 1, fp, byteswap, &chksum) != 1) {
160 E_ERROR(
"Failed to read number fo codebooks from %s\n", file_name);
164 *out_n_mgau = n_mgau;
167 if (bio_fread(&n_feat,
sizeof(int32), 1, fp, byteswap, &chksum) != 1) {
168 E_ERROR(
"Failed to read number of features from %s\n", file_name);
172 *out_n_feat = n_feat;
175 if (bio_fread(&n_density,
sizeof(int32), 1, fp, byteswap, &chksum) != 1) {
176 E_ERROR(
"fread(%s) (#density/codebook) failed\n", file_name);
178 *out_n_density = n_density;
181 veclen = ckd_calloc(n_feat,
sizeof(uint32));
182 *out_veclen = veclen;
183 if (bio_fread(veclen,
sizeof(int32), n_feat, fp, byteswap, &chksum) !=
185 E_ERROR(
"fread(%s) (feature-lengths) failed\n", file_name);
191 for (i = 0, blk = 0; i < n_feat; i++)
195 if (bio_fread(&n,
sizeof(int32), 1, fp, byteswap, &chksum) != 1) {
196 E_ERROR(
"Failed to read number of parameters from %s\n", file_name);
201 if (n != n_mgau * n_density * blk) {
203 (
"Number of parameters in %s(%d) doesn't match dimensions: %d x %d x %d\n",
204 file_name, n, n_mgau, n_density, blk);
210 out = (float32 ****) ckd_calloc_3d(n_mgau, n_feat, n_density,
212 buf = (float32 *) ckd_calloc(n,
sizeof(float32));
213 for (i = 0, l = 0; i < n_mgau; i++) {
214 for (j = 0; j < n_feat; j++) {
215 for (k = 0; k < n_density; k++) {
216 out[i][j][k] = &buf[l];
223 if (bio_fread(buf,
sizeof(float32), n, fp, byteswap, &chksum) != n) {
224 E_ERROR(
"Failed to read density data from file '%s'\n", file_name);
231 bio_verify_chksum(fp, byteswap, chksum);
233 if (fread(&tmp, 1, 1, fp) == 1) {
234 E_ERROR(
"More data than expected in %s\n", file_name);
242 E_INFO(
"%d codebook, %d feature, size: \n", n_mgau, n_feat);
243 for (i = 0; i < n_feat; i++)
244 E_INFO(
" %dx%d\n", n_density, veclen[i]);
250 gauden_param_free(mfcc_t **** p)
252 ckd_free(p[0][0][0]);
263 gauden_dist_precompute(
gauden_t * g, logmath_t *lmath, float32 varfloor)
265 int32 i, m, f, d, flen;
275 for (m = 0; m < g->
n_mgau; m++) {
276 for (f = 0; f < g->
n_feat; f++) {
280 for (d = 0, detp = g->
det[m][f]; d < g->n_density; d++, detp++) {
282 for (i = 0, varp = g->
var[m][f][d], meanp = g->
mean[m][f][d];
283 i < flen; i++, varp++, meanp++) {
284 float32 *fvarp = (float32 *)varp;
287 float32 *fmp = (float32 *)meanp;
288 *meanp = FLOAT2MFCC(*fmp);
290 if (*fvarp < varfloor) {
294 *detp += (mfcc_t)logmath_log(lmath,
295 1.0 / sqrt(*fvarp * 2.0 * M_PI));
297 *varp = (mfcc_t)logmath_ln_to_log(lmath,
298 (1.0 / (*fvarp * 2.0)));
304 E_INFO(
"%d variance values floored\n", floored);
311 gauden_init(
char const *meanfile,
char const *varfile, float32 varfloor, logmath_t *lmath)
313 int32 i, m, f, d, *flen;
316 assert(meanfile != NULL);
317 assert(varfile != NULL);
318 assert(varfloor > 0.0);
325 if (g->
mean == NULL) {
328 g->
var = (mfcc_t ****)gauden_param_read(varfile, &m, &f, &d, &flen);
329 if (g->
var == NULL) {
336 (
"Mixture-gaussians dimensions for means and variances differ\n");
341 for (i = 0; i < g->
n_feat; i++) {
342 if (g->
featlen[i] != flen[i]) {
343 E_FATAL(
"Feature lengths for means and variances differ\n");
352 gauden_dist_precompute(g, lmath, varfloor);
363 gauden_param_free(g->
mean);
365 gauden_param_free(g->
var);
375 compute_dist_all(
gauden_dist_t * out_dist, mfcc_t* obs, int32 featlen,
376 mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
381 for (d = 0; d < n_density; ++d) {
390 for (i = 0; i < featlen; i++) {
395 diff = obs[i] - m[i];
396 dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
402 diff = obs[i] - m[i];
405 dval -= diff * diff * v[i];
409 out_dist[d].
dist = dval;
423 mfcc_t * obs, int32 featlen,
424 mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
431 if (n_top >= n_density)
432 return (compute_dist_all
433 (out_dist, obs, featlen, mean, var, det, n_density));
435 for (i = 0; i < n_top; i++)
436 out_dist[i].dist = WORST_DIST;
437 worst = &(out_dist[n_top - 1]);
439 for (d = 0; d < n_density; d++) {
448 for (i = 0; (i < featlen) && (dval >= worst->
dist); i++) {
453 diff = obs[i] - m[i];
454 dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
460 diff = obs[i] - m[i];
463 dval -= diff * diff * v[i];
467 if ((i < featlen) || (dval < worst->dist))
471 for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++);
473 for (j = n_top - 1; j > i; --j)
474 out_dist[j] = out_dist[j - 1];
475 out_dist[i].
dist = dval;
490 int mgau, int32 n_top, mfcc_t** obs,
gauden_dist_t ** out_dist)
494 assert((n_top > 0) && (n_top <= g->n_density));
496 for (f = 0; f < g->
n_feat; f++) {
497 compute_dist(out_dist[f], n_top,
499 g->
mean[mgau][f], g->
var[mgau][f], g->
det[mgau][f],
501 E_DEBUG(3, (
"Top CW(%d,%d) = %d %d\n", mgau, f, out_dist[f][0].
id,
511 int32 i, m, f, d, *flen;
515 gauden_param_free(g->
mean);
517 gauden_param_free(g->
var);
528 g->
var = (mfcc_t ****)gauden_param_read(cmd_ln_str_r(config,
"_var"), &m, &f, &d, &flen);
533 (
"Mixture-gaussians dimensions for means and variances differ\n");
534 for (i = 0; i < g->
n_feat; i++)
536 E_FATAL(
"Feature lengths for means and variances differ\n");
540 for (i = 0; i < g->
n_mgau; ++i) {
541 for (f = 0; f < g->
n_feat; ++f) {
543 temp = (float64 *) ckd_calloc(g->
featlen[f],
sizeof(float64));
547 for (l = 0; l < g->
featlen[f]; l++) {
549 for (m = 0; m < g->
featlen[f]; m++) {
551 temp[l] += mllr->
A[f][0][l][m] * g->
mean[i][f][d][m];
553 temp[l] += mllr->
b[f][0][l];
556 for (l = 0; l < g->
featlen[f]; l++) {
557 g->
mean[i][f][d][l] = (float32) temp[l];
558 g->
var[i][f][d][l] *= mllr->
h[f][0][l];
567 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