00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <assert.h>
00043 #include <limits.h>
00044 #include <math.h>
00045 #if defined(__ADSPBLACKFIN__)
00046 #elif !defined(_WIN32_WCE)
00047 #include <sys/types.h>
00048 #endif
00049
00050 #ifndef M_PI
00051 #define M_PI 3.14159265358979323846
00052 #endif
00053
00054
00055 #include <sphinx_config.h>
00056 #include <cmd_ln.h>
00057 #include <fixpoint.h>
00058 #include <ckd_alloc.h>
00059 #include <bio.h>
00060 #include <err.h>
00061 #include <prim_type.h>
00062 #include <assert.h>
00063
00064
00065 #include "tied_mgau_common.h"
00066 #include "ptm_mgau.h"
00067 #include "posixwin32.h"
00068
00069 static ps_mgaufuncs_t ptm_mgau_funcs = {
00070 "ptm",
00071 &ptm_mgau_frame_eval,
00072 &ptm_mgau_mllr_transform,
00073 &ptm_mgau_free
00074 };
00075
00076 #define COMPUTE_GMM_MAP(_idx) \
00077 diff[_idx] = obs[_idx] - mean[_idx]; \
00078 sqdiff[_idx] = MFCCMUL(diff[_idx], diff[_idx]); \
00079 compl[_idx] = MFCCMUL(sqdiff[_idx], var[_idx]);
00080 #define COMPUTE_GMM_REDUCE(_idx) \
00081 d = GMMSUB(d, compl[_idx]);
00082
00083 static void
00084 insertion_sort_topn(ptm_topn_t *topn, int i, int32 d)
00085 {
00086 ptm_topn_t vtmp;
00087 int j;
00088
00089 topn[i].score = d;
00090 if (i == 0)
00091 return;
00092 vtmp = topn[i];
00093 for (j = i - 1; j >= 0 && d > topn[j].score; j--) {
00094 topn[j + 1] = topn[j];
00095 }
00096 topn[j + 1] = vtmp;
00097 }
00098
00099 static int
00100 eval_topn(ptm_mgau_t *s, int cb, int feat, mfcc_t *z)
00101 {
00102 ptm_topn_t *topn;
00103 int i, ceplen;
00104
00105 topn = s->f->topn[cb][feat];
00106 ceplen = s->g->featlen[feat];
00107
00108 for (i = 0; i < s->max_topn; i++) {
00109 mfcc_t *mean, diff[4], sqdiff[4], compl[4];
00110 mfcc_t *var, d;
00111 mfcc_t *obs;
00112 int32 cw, j;
00113
00114 cw = topn[i].cw;
00115 mean = s->g->mean[cb][feat][0] + cw * ceplen;
00116 var = s->g->var[cb][feat][0] + cw * ceplen;
00117 d = s->g->det[cb][feat][cw];
00118 obs = z;
00119 for (j = 0; j < ceplen % 4; ++j) {
00120 diff[0] = *obs++ - *mean++;
00121 sqdiff[0] = MFCCMUL(diff[0], diff[0]);
00122 compl[0] = MFCCMUL(sqdiff[0], *var);
00123 d = GMMSUB(d, compl[0]);
00124 ++var;
00125 }
00126
00127
00128 for (;j < ceplen; j += 4) {
00129 COMPUTE_GMM_MAP(0);
00130 COMPUTE_GMM_MAP(1);
00131 COMPUTE_GMM_MAP(2);
00132 COMPUTE_GMM_MAP(3);
00133 COMPUTE_GMM_REDUCE(0);
00134 COMPUTE_GMM_REDUCE(1);
00135 COMPUTE_GMM_REDUCE(2);
00136 COMPUTE_GMM_REDUCE(3);
00137 var += 4;
00138 obs += 4;
00139 mean += 4;
00140 }
00141 insertion_sort_topn(topn, i, (int32)d);
00142 }
00143
00144 return topn[0].score;
00145 }
00146
00147
00148
00149 static void
00150 insertion_sort_cb(ptm_topn_t **cur, ptm_topn_t *worst, ptm_topn_t *best,
00151 int cw, int32 intd)
00152 {
00153 for (*cur = worst - 1; *cur >= best && intd >= (*cur)->score; --*cur)
00154 memcpy(*cur + 1, *cur, sizeof(**cur));
00155 ++*cur;
00156 (*cur)->cw = cw;
00157 (*cur)->score = intd;
00158 }
00159
00160 static int
00161 eval_cb(ptm_mgau_t *s, int cb, int feat, mfcc_t *z)
00162 {
00163 ptm_topn_t *worst, *best, *topn;
00164 mfcc_t *mean;
00165 mfcc_t *var, *det, *detP, *detE;
00166 int32 i, ceplen;
00167
00168 best = topn = s->f->topn[cb][feat];
00169 worst = topn + (s->max_topn - 1);
00170 mean = s->g->mean[cb][feat][0];
00171 var = s->g->var[cb][feat][0];
00172 det = s->g->det[cb][feat];
00173 detE = det + s->g->n_density;
00174 ceplen = s->g->featlen[feat];
00175
00176 for (detP = det; detP < detE; ++detP) {
00177 mfcc_t diff[4], sqdiff[4], compl[4];
00178 mfcc_t d, thresh;
00179 mfcc_t *obs;
00180 ptm_topn_t *cur;
00181 int32 cw, j;
00182
00183 d = *detP;
00184 thresh = (mfcc_t) worst->score;
00185 obs = z;
00186 cw = detP - det;
00187
00188
00189
00190
00191 for (j = 0; (j < ceplen % 4) && (d >= thresh); ++j) {
00192 diff[0] = *obs++ - *mean++;
00193 sqdiff[0] = MFCCMUL(diff[0], diff[0]);
00194 compl[0] = MFCCMUL(sqdiff[0], *var++);
00195 d = GMMSUB(d, compl[0]);
00196 }
00197
00198
00199
00200 for (; j < ceplen && d >= thresh; j += 4) {
00201 COMPUTE_GMM_MAP(0);
00202 COMPUTE_GMM_MAP(1);
00203 COMPUTE_GMM_MAP(2);
00204 COMPUTE_GMM_MAP(3);
00205 COMPUTE_GMM_REDUCE(0);
00206 COMPUTE_GMM_REDUCE(1);
00207 COMPUTE_GMM_REDUCE(2);
00208 COMPUTE_GMM_REDUCE(3);
00209 var += 4;
00210 obs += 4;
00211 mean += 4;
00212 }
00213 if (j < ceplen) {
00214
00215 mean += (ceplen - j);
00216 var += (ceplen - j);
00217 continue;
00218 }
00219 if (d < thresh)
00220 continue;
00221 for (i = 0; i < s->max_topn; i++) {
00222
00223 if (topn[i].cw == cw)
00224 break;
00225 }
00226 if (i < s->max_topn)
00227 continue;
00228 insertion_sort_cb(&cur, worst, best, cw, (int32)d);
00229 }
00230
00231 return best->score;
00232 }
00233
00237 static int
00238 ptm_mgau_codebook_eval(ptm_mgau_t *s, mfcc_t **z, int frame)
00239 {
00240 int i, j;
00241
00242
00243 for (i = 0; i < s->g->n_mgau; ++i)
00244 for (j = 0; j < s->g->n_feat; ++j)
00245 eval_topn(s, i, j, z[j]);
00246
00247
00248 if (frame % s->ds_ratio)
00249 return 0;
00250
00251
00252 for (i = 0; i < s->g->n_mgau; ++i) {
00253 if (bitvec_is_clear(s->f->mgau_active, i))
00254 continue;
00255 for (j = 0; j < s->g->n_feat; ++j) {
00256 eval_cb(s, i, j, z[j]);
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 for (j = 0; j < s->g->n_feat; ++j) {
00269 int32 norm = 0x7fffffff;
00270 for (i = 0; i < s->g->n_mgau; ++i) {
00271 if (bitvec_is_clear(s->f->mgau_active, i))
00272 continue;
00273 if (norm > s->f->topn[i][j][0].score >> SENSCR_SHIFT)
00274 norm = s->f->topn[i][j][0].score >> SENSCR_SHIFT;
00275 }
00276 assert(norm != 0x7fffffff);
00277 for (i = 0; i < s->g->n_mgau; ++i) {
00278 int32 k;
00279 if (bitvec_is_clear(s->f->mgau_active, i))
00280 continue;
00281 for (k = 0; k < s->max_topn; ++k) {
00282 s->f->topn[i][j][k].score >>= SENSCR_SHIFT;
00283 s->f->topn[i][j][k].score -= norm;
00284 s->f->topn[i][j][k].score = -s->f->topn[i][j][k].score;
00285 if (s->f->topn[i][j][k].score > MAX_NEG_ASCR)
00286 s->f->topn[i][j][k].score = MAX_NEG_ASCR;
00287 }
00288 }
00289 }
00290
00291 return 0;
00292 }
00293
00294 static int
00295 ptm_mgau_calc_cb_active(ptm_mgau_t *s, uint8 *senone_active,
00296 int32 n_senone_active, int compallsen)
00297 {
00298 int i, lastsen;
00299
00300 if (compallsen) {
00301 bitvec_set_all(s->f->mgau_active, s->g->n_mgau);
00302 return 0;
00303 }
00304 bitvec_clear_all(s->f->mgau_active, s->g->n_mgau);
00305 for (lastsen = i = 0; i < n_senone_active; ++i) {
00306 int sen = senone_active[i] + lastsen;
00307 int cb = s->sen2cb[sen];
00308 bitvec_set(s->f->mgau_active, cb);
00309 lastsen = sen;
00310 }
00311 E_DEBUG(1, ("Active codebooks:"));
00312 for (i = 0; i < s->g->n_mgau; ++i) {
00313 if (bitvec_is_clear(s->f->mgau_active, i))
00314 continue;
00315 E_DEBUGCONT(1, (" %d", i));
00316 }
00317 E_DEBUGCONT(1, ("\n"));
00318 return 0;
00319 }
00320
00324 static int
00325 ptm_mgau_senone_eval(ptm_mgau_t *s, int16 *senone_scores,
00326 uint8 *senone_active, int32 n_senone_active,
00327 int compall)
00328 {
00329 int i, lastsen, bestscore;
00330
00331 memset(senone_scores, 0, s->n_sen * sizeof(*senone_scores));
00332
00333
00334
00335
00336
00337 if (compall)
00338 n_senone_active = s->n_sen;
00339 bestscore = 0x7fffffff;
00340 for (lastsen = i = 0; i < n_senone_active; ++i) {
00341 int sen, f, cb;
00342 int ascore;
00343
00344 if (compall)
00345 sen = i;
00346 else
00347 sen = senone_active[i] + lastsen;
00348 lastsen = sen;
00349 cb = s->sen2cb[sen];
00350
00351 if (bitvec_is_clear(s->f->mgau_active, cb)) {
00352 int j;
00353
00354
00355
00356
00357 for (f = 0; f < s->g->n_feat; ++f) {
00358 for (j = 0; j < s->max_topn; ++j) {
00359 s->f->topn[cb][f][j].score = MAX_NEG_ASCR;
00360 }
00361 }
00362 }
00363
00364
00365 ascore = 0;
00366 for (f = 0; f < s->g->n_feat; ++f) {
00367 ptm_topn_t *topn;
00368 int j, fden = 0;
00369 topn = s->f->topn[cb][f];
00370 for (j = 0; j < s->max_topn; ++j) {
00371 int mixw;
00372
00373 if (s->mixw_cb) {
00374 int dcw = s->mixw[f][topn[j].cw][sen/2];
00375 dcw = (dcw & 1) ? dcw >> 4 : dcw & 0x0f;
00376 mixw = s->mixw_cb[dcw];
00377 }
00378 else {
00379 mixw = s->mixw[f][topn[j].cw][sen];
00380 }
00381 if (j == 0)
00382 fden = mixw + topn[j].score;
00383 else
00384 fden = fast_logmath_add(s->lmath_8b, fden,
00385 mixw + topn[j].score);
00386 E_DEBUG(3, ("fden[%d][%d] l+= %d + %d = %d\n",
00387 sen, f, mixw, topn[j].score, fden));
00388 }
00389 ascore += fden;
00390 }
00391 if (ascore < bestscore) bestscore = ascore;
00392 senone_scores[sen] = ascore;
00393 }
00394
00395
00396 for (i = 0; i < s->n_sen; ++i) {
00397 senone_scores[i] -= bestscore;
00398 }
00399
00400 return 0;
00401 }
00402
00406 int32
00407 ptm_mgau_frame_eval(ps_mgau_t *ps,
00408 int16 *senone_scores,
00409 uint8 *senone_active,
00410 int32 n_senone_active,
00411 mfcc_t ** featbuf, int32 frame,
00412 int32 compallsen)
00413 {
00414 ptm_mgau_t *s = (ptm_mgau_t *)ps;
00415 int fast_eval_idx;
00416
00417
00418
00419
00420
00421
00422
00423 fast_eval_idx = frame % s->n_fast_hist;
00424 s->f = s->hist + fast_eval_idx;
00425
00426
00427
00428 if (frame >= ps_mgau_base(ps)->frame_idx) {
00429 ptm_fast_eval_t *lastf;
00430
00431
00432
00433 if (fast_eval_idx == 0)
00434 lastf = s->hist + s->n_fast_hist - 1;
00435 else
00436 lastf = s->hist + fast_eval_idx - 1;
00437
00438 memcpy(s->f->topn[0][0], lastf->topn[0][0],
00439 s->g->n_mgau * s->g->n_feat * s->max_topn * sizeof(ptm_topn_t));
00440
00441
00442 ptm_mgau_calc_cb_active(s, senone_active, n_senone_active, compallsen);
00443
00444 ptm_mgau_codebook_eval(s, featbuf, frame);
00445 }
00446
00447 ptm_mgau_senone_eval(s, senone_scores, senone_active,
00448 n_senone_active, compallsen);
00449
00450 return 0;
00451 }
00452
00453 static int32
00454 read_sendump(ptm_mgau_t *s, bin_mdef_t *mdef, char const *file)
00455 {
00456 FILE *fp;
00457 char line[1000];
00458 int32 i, n, r, c;
00459 int32 do_swap, do_mmap;
00460 size_t filesize, offset;
00461 int n_clust = 0;
00462 int n_feat = s->g->n_feat;
00463 int n_density = s->g->n_density;
00464 int n_sen = bin_mdef_n_sen(mdef);
00465 int n_bits = 8;
00466
00467 s->n_sen = n_sen;
00468 do_mmap = cmd_ln_boolean_r(s->config, "-mmap");
00469
00470 if ((fp = fopen(file, "rb")) == NULL)
00471 return -1;
00472
00473 E_INFO("Loading senones from dump file %s\n", file);
00474
00475 if (fread(&n, sizeof(int32), 1, fp) != 1) {
00476 E_ERROR_SYSTEM("Failed to read title size from %s", file);
00477 goto error_out;
00478 }
00479
00480 do_swap = 0;
00481 if (n < 1 || n > 999) {
00482 SWAP_INT32(&n);
00483 if (n < 1 || n > 999) {
00484 E_ERROR("Title length %x in dump file %s out of range\n", n, file);
00485 goto error_out;
00486 }
00487 do_swap = 1;
00488 }
00489 if (fread(line, sizeof(char), n, fp) != n) {
00490 E_ERROR_SYSTEM("Cannot read title");
00491 goto error_out;
00492 }
00493 if (line[n - 1] != '\0') {
00494 E_ERROR("Bad title in dump file\n");
00495 goto error_out;
00496 }
00497 E_INFO("%s\n", line);
00498
00499
00500 if (fread(&n, sizeof(n), 1, fp) != 1) {
00501 E_ERROR_SYSTEM("Failed to read header size from %s", file);
00502 goto error_out;
00503 }
00504 if (do_swap) SWAP_INT32(&n);
00505 if (fread(line, sizeof(char), n, fp) != n) {
00506 E_ERROR_SYSTEM("Cannot read header");
00507 goto error_out;
00508 }
00509 if (line[n - 1] != '\0') {
00510 E_ERROR("Bad header in dump file\n");
00511 goto error_out;
00512 }
00513
00514
00515 for (;;) {
00516 if (fread(&n, sizeof(n), 1, fp) != 1) {
00517 E_ERROR_SYSTEM("Failed to read header string size from %s", file);
00518 goto error_out;
00519 }
00520 if (do_swap) SWAP_INT32(&n);
00521 if (n == 0)
00522 break;
00523 if (fread(line, sizeof(char), n, fp) != n) {
00524 E_ERROR_SYSTEM("Cannot read header");
00525 goto error_out;
00526 }
00527
00528 if (!strncmp(line, "feature_count ", strlen("feature_count "))) {
00529 n_feat = atoi(line + strlen("feature_count "));
00530 }
00531 if (!strncmp(line, "mixture_count ", strlen("mixture_count "))) {
00532 n_density = atoi(line + strlen("mixture_count "));
00533 }
00534 if (!strncmp(line, "model_count ", strlen("model_count "))) {
00535 n_sen = atoi(line + strlen("model_count "));
00536 }
00537 if (!strncmp(line, "cluster_count ", strlen("cluster_count "))) {
00538 n_clust = atoi(line + strlen("cluster_count "));
00539 }
00540 if (!strncmp(line, "cluster_bits ", strlen("cluster_bits "))) {
00541 n_bits = atoi(line + strlen("cluster_bits "));
00542 }
00543 }
00544
00545
00546 c = n_sen;
00547 r = n_density;
00548 if (n_clust == 0) {
00549
00550 if (fread(&r, sizeof(r), 1, fp) != 1) {
00551 E_ERROR_SYSTEM("Cannot read #rows");
00552 goto error_out;
00553 }
00554 if (do_swap) SWAP_INT32(&r);
00555 if (fread(&c, sizeof(c), 1, fp) != 1) {
00556 E_ERROR_SYSTEM("Cannot read #columns");
00557 goto error_out;
00558 }
00559 if (do_swap) SWAP_INT32(&c);
00560 E_INFO("Rows: %d, Columns: %d\n", r, c);
00561 }
00562
00563 if (n_feat != s->g->n_feat) {
00564 E_ERROR("Number of feature streams mismatch: %d != %d\n",
00565 n_feat, s->g->n_feat);
00566 goto error_out;
00567 }
00568 if (n_density != s->g->n_density) {
00569 E_ERROR("Number of densities mismatch: %d != %d\n",
00570 n_density, s->g->n_density);
00571 goto error_out;
00572 }
00573 if (n_sen != s->n_sen) {
00574 E_ERROR("Number of senones mismatch: %d != %d\n",
00575 n_sen, s->n_sen);
00576 goto error_out;
00577 }
00578
00579 if (!((n_clust == 0) || (n_clust == 15) || (n_clust == 16))) {
00580 E_ERROR("Cluster count must be 0, 15, or 16\n");
00581 goto error_out;
00582 }
00583 if (n_clust == 15)
00584 ++n_clust;
00585
00586 if (!((n_bits == 8) || (n_bits == 4))) {
00587 E_ERROR("Cluster count must be 4 or 8\n");
00588 goto error_out;
00589 }
00590
00591 if (do_mmap) {
00592 E_INFO("Using memory-mapped I/O for senones\n");
00593 }
00594 offset = ftell(fp);
00595 fseek(fp, 0, SEEK_END);
00596 filesize = ftell(fp);
00597 fseek(fp, offset, SEEK_SET);
00598
00599
00600 if (do_mmap) {
00601 s->sendump_mmap = mmio_file_read(file);
00602
00603 if (n_clust) {
00604 s->mixw_cb = ((uint8 *) mmio_file_ptr(s->sendump_mmap)) + offset;
00605 offset += n_clust;
00606 }
00607 }
00608 else {
00609
00610 if (n_clust) {
00611 s->mixw_cb = ckd_calloc(1, n_clust);
00612 if (fread(s->mixw_cb, 1, n_clust, fp) != (size_t) n_clust) {
00613 E_ERROR("Failed to read %d bytes from sendump\n", n_clust);
00614 goto error_out;
00615 }
00616 }
00617 }
00618
00619
00620 if (s->sendump_mmap) {
00621 s->mixw = ckd_calloc_2d(n_feat, n_density, sizeof(*s->mixw));
00622 for (n = 0; n < n_feat; n++) {
00623 int step = c;
00624 if (n_bits == 4)
00625 step = (step + 1) / 2;
00626 for (i = 0; i < r; i++) {
00627 s->mixw[n][i] = ((uint8 *) mmio_file_ptr(s->sendump_mmap)) + offset;
00628 offset += step;
00629 }
00630 }
00631 }
00632 else {
00633 s->mixw = ckd_calloc_3d(n_feat, n_density, n_sen, sizeof(***s->mixw));
00634
00635 for (n = 0; n < n_feat; n++) {
00636 int step = c;
00637 if (n_bits == 4)
00638 step = (step + 1) / 2;
00639 for (i = 0; i < r; i++) {
00640 if (fread(s->mixw[n][i], sizeof(***s->mixw), step, fp)
00641 != (size_t) step) {
00642 E_ERROR("Failed to read %d bytes from sendump\n", step);
00643 goto error_out;
00644 }
00645 }
00646 }
00647 }
00648
00649 fclose(fp);
00650 return 0;
00651 error_out:
00652 fclose(fp);
00653 return -1;
00654 }
00655
00656 static int32
00657 read_mixw(ptm_mgau_t * s, char const *file_name, double SmoothMin)
00658 {
00659 char **argname, **argval;
00660 char eofchk;
00661 FILE *fp;
00662 int32 byteswap, chksum_present;
00663 uint32 chksum;
00664 float32 *pdf;
00665 int32 i, f, c, n;
00666 int32 n_sen;
00667 int32 n_feat;
00668 int32 n_comp;
00669 int32 n_err;
00670
00671 E_INFO("Reading mixture weights file '%s'\n", file_name);
00672
00673 if ((fp = fopen(file_name, "rb")) == NULL)
00674 E_FATAL("fopen(%s,rb) failed\n", file_name);
00675
00676
00677 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
00678 E_FATAL("bio_readhdr(%s) failed\n", file_name);
00679
00680
00681 chksum_present = 0;
00682 for (i = 0; argname[i]; i++) {
00683 if (strcmp(argname[i], "version") == 0) {
00684 if (strcmp(argval[i], MGAU_MIXW_VERSION) != 0)
00685 E_WARN("Version mismatch(%s): %s, expecting %s\n",
00686 file_name, argval[i], MGAU_MIXW_VERSION);
00687 }
00688 else if (strcmp(argname[i], "chksum0") == 0) {
00689 chksum_present = 1;
00690 }
00691 }
00692 bio_hdrarg_free(argname, argval);
00693 argname = argval = NULL;
00694
00695 chksum = 0;
00696
00697
00698 if ((bio_fread(&n_sen, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
00699 || (bio_fread(&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) !=
00700 1)
00701 || (bio_fread(&n_comp, sizeof(int32), 1, fp, byteswap, &chksum) !=
00702 1)
00703 || (bio_fread(&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)) {
00704 E_FATAL("bio_fread(%s) (arraysize) failed\n", file_name);
00705 }
00706 if (n_feat != s->g->n_feat)
00707 E_FATAL("#Features streams(%d) != %d\n", n_feat, s->g->n_feat);
00708 if (n != n_sen * n_feat * n_comp) {
00709 E_FATAL
00710 ("%s: #float32s(%d) doesn't match header dimensions: %d x %d x %d\n",
00711 file_name, i, n_sen, n_feat, n_comp);
00712 }
00713
00714
00715
00716
00717 s->n_sen = n_sen;
00718
00719
00720 s->mixw = ckd_calloc_3d(s->g->n_feat, s->g->n_density,
00721 n_sen, sizeof(***s->mixw));
00722
00723
00724 pdf = (float32 *) ckd_calloc(n_comp, sizeof(float32));
00725
00726
00727 n_err = 0;
00728 for (i = 0; i < n_sen; i++) {
00729 for (f = 0; f < n_feat; f++) {
00730 if (bio_fread((void *) pdf, sizeof(float32),
00731 n_comp, fp, byteswap, &chksum) != n_comp) {
00732 E_FATAL("bio_fread(%s) (arraydata) failed\n", file_name);
00733 }
00734
00735
00736 if (vector_sum_norm(pdf, n_comp) <= 0.0)
00737 n_err++;
00738 vector_floor(pdf, n_comp, SmoothMin);
00739 vector_sum_norm(pdf, n_comp);
00740
00741
00742 for (c = 0; c < n_comp; c++) {
00743 int32 qscr;
00744
00745 qscr = -logmath_log(s->lmath_8b, pdf[c]);
00746 if ((qscr > MAX_NEG_MIXW) || (qscr < 0))
00747 qscr = MAX_NEG_MIXW;
00748 s->mixw[f][c][i] = qscr;
00749 }
00750 }
00751 }
00752 if (n_err > 0)
00753 E_ERROR("Weight normalization failed for %d senones\n", n_err);
00754
00755 ckd_free(pdf);
00756
00757 if (chksum_present)
00758 bio_verify_chksum(fp, byteswap, chksum);
00759
00760 if (fread(&eofchk, 1, 1, fp) == 1)
00761 E_FATAL("More data than expected in %s\n", file_name);
00762
00763 fclose(fp);
00764
00765 E_INFO("Read %d x %d x %d mixture weights\n", n_sen, n_feat, n_comp);
00766 return n_sen;
00767 }
00768
00769 ps_mgau_t *
00770 ptm_mgau_init(acmod_t *acmod)
00771 {
00772 ptm_mgau_t *s;
00773 ps_mgau_t *ps;
00774 char const *sendump_path;
00775 int i;
00776
00777 s = ckd_calloc(1, sizeof(*s));
00778 s->config = acmod->config;
00779
00780 s->lmath = logmath_retain(acmod->lmath);
00781
00782 s->lmath_8b = logmath_init(logmath_get_base(acmod->lmath), SENSCR_SHIFT, TRUE);
00783 if (s->lmath_8b == NULL)
00784 goto error_out;
00785
00786 if (logmath_get_width(s->lmath_8b) != 1) {
00787 E_ERROR("Log base %f is too small to represent add table in 8 bits\n",
00788 logmath_get_base(s->lmath_8b));
00789 goto error_out;
00790 }
00791
00792
00793 if ((s->g = gauden_init(cmd_ln_str_r(s->config, "-mean"),
00794 cmd_ln_str_r(s->config, "-var"),
00795 cmd_ln_float32_r(s->config, "-varfloor"),
00796 s->lmath)) == NULL)
00797 goto error_out;
00798
00799
00800 if (s->g->n_mgau > 256) {
00801 E_ERROR("Number of codebooks exceeds 256: %d\n", s->g->n_mgau);
00802 goto error_out;
00803 }
00804
00805 if (s->g->n_feat != feat_dimension1(acmod->fcb)) {
00806 E_ERROR("Number of streams does not match: %d != %d\n",
00807 s->g->n_feat, feat_dimension(acmod->fcb));
00808 goto error_out;
00809 }
00810 for (i = 0; i < s->g->n_feat; ++i) {
00811 if (s->g->featlen[i] != feat_dimension2(acmod->fcb, i)) {
00812 E_ERROR("Dimension of stream %d does not match: %d != %d\n",
00813 s->g->featlen[i], feat_dimension2(acmod->fcb, i));
00814 goto error_out;
00815 }
00816 }
00817
00818 if ((sendump_path = cmd_ln_str_r(s->config, "-sendump"))) {
00819 if (read_sendump(s, acmod->mdef, sendump_path) < 0) {
00820 goto error_out;
00821 }
00822 }
00823 else {
00824 if (read_mixw(s, cmd_ln_str_r(s->config, "-mixw"),
00825 cmd_ln_float32_r(s->config, "-mixwfloor")) < 0) {
00826 goto error_out;
00827 }
00828 }
00829 s->ds_ratio = cmd_ln_int32_r(s->config, "-ds");
00830 s->max_topn = cmd_ln_int32_r(s->config, "-topn");
00831 E_INFO("Maximum top-N: %d\n", s->max_topn);
00832
00833
00834
00835 s->sen2cb = ckd_calloc(s->n_sen, sizeof(*s->sen2cb));
00836 for (i = 0; i < s->n_sen; ++i)
00837 s->sen2cb[i] = bin_mdef_sen2cimap(acmod->mdef, i);
00838
00839
00840
00841
00842 s->n_fast_hist = cmd_ln_int32_r(s->config, "-pl_window") + 2;
00843 s->hist = ckd_calloc(s->n_fast_hist, sizeof(*s->hist));
00844
00845 s->f = s->hist;
00846 for (i = 0; i < s->n_fast_hist; ++i) {
00847 int j, k, m;
00848
00849 s->hist[i].topn = ckd_calloc_3d(s->g->n_mgau, s->g->n_feat,
00850 s->max_topn, sizeof(ptm_topn_t));
00851
00852 for (j = 0; j < s->g->n_mgau; ++j) {
00853 for (k = 0; k < s->g->n_feat; ++k) {
00854 for (m = 0; m < s->max_topn; ++m) {
00855 s->hist[i].topn[j][k][m].cw = m;
00856 s->hist[i].topn[j][k][m].score = WORST_DIST;
00857 }
00858 }
00859 }
00860
00861
00862 s->hist[i].mgau_active = bitvec_alloc(s->g->n_mgau);
00863
00864 bitvec_set_all(s->hist[i].mgau_active, s->g->n_mgau);
00865 }
00866
00867 ps = (ps_mgau_t *)s;
00868 ps->vt = &ptm_mgau_funcs;
00869 return ps;
00870 error_out:
00871 ptm_mgau_free(ps_mgau_base(s));
00872 return NULL;
00873 }
00874
00875 int
00876 ptm_mgau_mllr_transform(ps_mgau_t *ps,
00877 ps_mllr_t *mllr)
00878 {
00879 ptm_mgau_t *s = (ptm_mgau_t *)ps;
00880 return gauden_mllr_transform(s->g, mllr, s->config);
00881 }
00882
00883 void
00884 ptm_mgau_free(ps_mgau_t *ps)
00885 {
00886 ptm_mgau_t *s = (ptm_mgau_t *)ps;
00887
00888 logmath_free(s->lmath);
00889 logmath_free(s->lmath_8b);
00890 if (s->sendump_mmap) {
00891 ckd_free_2d(s->mixw);
00892 mmio_file_unmap(s->sendump_mmap);
00893 }
00894 else {
00895 ckd_free_3d(s->mixw);
00896 }
00897 ckd_free(s->sen2cb);
00898 gauden_free(s->g);
00899 ckd_free(s);
00900 }