45 #if defined(__ADSPBLACKFIN__)
46 #elif !defined(_WIN32_WCE)
47 #include <sys/types.h>
51 #include <sphinx_config.h>
52 #include <sphinxbase/cmd_ln.h>
53 #include <sphinxbase/fixpoint.h>
54 #include <sphinxbase/ckd_alloc.h>
55 #include <sphinxbase/bio.h>
56 #include <sphinxbase/err.h>
57 #include <sphinxbase/prim_type.h>
60 #include "s2_semi_mgau.h"
65 s2_semi_mgau_frame_eval,
66 s2_semi_mgau_mllr_transform,
84 for (i = 0; i < s->max_topn; i++) {
85 mfcc_t *mean, diff, sqdiff, compl;
91 cw = topn[i].codeword;
92 mean = s->g->
mean[0][feat][0] + cw * ceplen;
93 var = s->g->
var[0][feat][0] + cw * ceplen;
94 d = s->g->
det[0][feat][cw];
96 for (j = 0; j < ceplen; j++) {
97 diff = *obs++ - *mean++;
98 sqdiff = MFCCMUL(diff, diff);
99 compl = MFCCMUL(sqdiff, *var);
103 topn[i].score = (int32)d;
107 for (j = i - 1; j >= 0 && (int32)d > topn[j].score; j--) {
108 topn[j + 1] = topn[j];
119 mfcc_t *var, *det, *detP, *detE;
122 best = topn = s->
f[feat];
123 worst = topn + (s->max_topn - 1);
124 mean = s->g->
mean[0][feat][0];
125 var = s->g->
var[0][feat][0];
126 det = s->g->
det[0][feat];
130 for (detP = det; detP < detE; ++detP) {
131 mfcc_t diff, sqdiff, compl;
139 cw = (int)(detP - det);
140 for (j = 0; (j < ceplen) && (d >= worst->score); ++j) {
141 diff = *obs++ - *mean++;
142 sqdiff = MFCCMUL(diff, diff);
143 compl = MFCCMUL(sqdiff, *var);
149 mean += (ceplen - j);
153 if ((int32)d < worst->score)
155 for (i = 0; i < s->max_topn; i++) {
157 if (topn[i].codeword == cw)
163 for (cur = worst - 1; cur >= best && (int32)d >= cur->score; --cur)
167 cur->score = (int32)d;
172 mgau_dist(
s2_semi_mgau_t * s, int32 frame, int32 feat, mfcc_t * z)
174 eval_topn(s, feat, z);
177 if (frame % s->ds_ratio)
194 for (j = 0; j < s->max_topn; ++j) {
195 s->
f[feat][j].score = -((s->
f[feat][j].score >>
SENSCR_SHIFT) - norm);
198 if (s->topn_beam[feat] && s->
f[feat][j].score > s->topn_beam[feat])
206 int16 *senone_scores, uint8 *senone_active,
207 int32 n_senone_active)
210 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3, *pid_cw4, *pid_cw5;
212 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
213 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
214 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
215 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
216 pid_cw4 = s->mixw[i][s->
f[i][4].codeword];
217 pid_cw5 = s->mixw[i][s->
f[i][5].codeword];
219 for (l = j = 0; j < n_senone_active; j++) {
220 int sen = senone_active[j] + l;
221 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
224 pid_cw1[sen] + s->
f[i][1].score);
226 pid_cw2[sen] + s->
f[i][2].score);
228 pid_cw3[sen] + s->
f[i][3].score);
230 pid_cw4[sen] + s->
f[i][4].score);
232 pid_cw5[sen] + s->
f[i][5].score);
234 senone_scores[sen] += tmp;
242 int16 *senone_scores, uint8 *senone_active,
243 int32 n_senone_active)
246 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3, *pid_cw4;
248 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
249 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
250 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
251 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
252 pid_cw4 = s->mixw[i][s->
f[i][4].codeword];
254 for (l = j = 0; j < n_senone_active; j++) {
255 int sen = senone_active[j] + l;
256 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
259 pid_cw1[sen] + s->
f[i][1].score);
261 pid_cw2[sen] + s->
f[i][2].score);
263 pid_cw3[sen] + s->
f[i][3].score);
265 pid_cw4[sen] + s->
f[i][4].score);
267 senone_scores[sen] += tmp;
275 int16 *senone_scores, uint8 *senone_active,
276 int32 n_senone_active)
279 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3;
281 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
282 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
283 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
284 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
286 for (l = j = 0; j < n_senone_active; j++) {
287 int sen = senone_active[j] + l;
288 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
291 pid_cw1[sen] + s->
f[i][1].score);
293 pid_cw2[sen] + s->
f[i][2].score);
295 pid_cw3[sen] + s->
f[i][3].score);
297 senone_scores[sen] += tmp;
305 int16 *senone_scores, uint8 *senone_active,
306 int32 n_senone_active)
309 uint8 *pid_cw0, *pid_cw1, *pid_cw2;
311 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
312 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
313 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
315 for (l = j = 0; j < n_senone_active; j++) {
316 int sen = senone_active[j] + l;
317 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
320 pid_cw1[sen] + s->
f[i][1].score);
322 pid_cw2[sen] + s->
f[i][2].score);
324 senone_scores[sen] += tmp;
332 int16 *senone_scores, uint8 *senone_active,
333 int32 n_senone_active)
336 uint8 *pid_cw0, *pid_cw1;
338 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
339 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
341 for (l = j = 0; j < n_senone_active; j++) {
342 int sen = senone_active[j] + l;
343 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
346 pid_cw1[sen] + s->
f[i][1].score);
348 senone_scores[sen] += tmp;
356 int16 *senone_scores, uint8 *senone_active,
357 int32 n_senone_active)
362 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
363 for (l = j = 0; j < n_senone_active; j++) {
364 int sen = senone_active[j] + l;
365 int32 tmp = pid_cw0[sen] + s->
f[i][0].score;
366 senone_scores[sen] += tmp;
374 int16 *senone_scores, uint8 *senone_active,
375 int32 n_senone_active)
379 for (l = j = 0; j < n_senone_active; j++) {
380 int sen = senone_active[j] + l;
383 pid_cw = s->mixw[i][s->
f[i][0].codeword];
384 tmp = pid_cw[sen] + s->
f[i][0].score;
385 for (k = 1; k < topn; ++k) {
386 pid_cw = s->mixw[i][s->
f[i][k].codeword];
388 pid_cw[sen] + s->
f[i][k].score);
390 senone_scores[sen] += tmp;
398 int16 *senone_scores, uint8 *senone_active, int32 n_senone_active)
402 return get_scores_8b_feat_6(s, i, senone_scores,
403 senone_active, n_senone_active);
405 return get_scores_8b_feat_5(s, i, senone_scores,
406 senone_active, n_senone_active);
408 return get_scores_8b_feat_4(s, i, senone_scores,
409 senone_active, n_senone_active);
411 return get_scores_8b_feat_3(s, i, senone_scores,
412 senone_active, n_senone_active);
414 return get_scores_8b_feat_2(s, i, senone_scores,
415 senone_active, n_senone_active);
417 return get_scores_8b_feat_1(s, i, senone_scores,
418 senone_active, n_senone_active);
420 return get_scores_8b_feat_any(s, i, topn, senone_scores,
421 senone_active, n_senone_active);
426 get_scores_8b_feat_all(
s2_semi_mgau_t * s,
int i,
int topn, int16 *senone_scores)
430 for (j = 0; j < s->n_sen; j++) {
433 pid_cw = s->mixw[i][s->
f[i][0].codeword];
434 tmp = pid_cw[j] + s->
f[i][0].score;
435 for (k = 1; k < topn; ++k) {
436 pid_cw = s->mixw[i][s->
f[i][k].codeword];
438 pid_cw[j] + s->
f[i][k].score);
440 senone_scores[j] += tmp;
447 int16 *senone_scores, uint8 *senone_active,
448 int32 n_senone_active)
451 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3, *pid_cw4, *pid_cw5;
455 for (j = 0; j < 16; ++j) {
456 w_den[0][j] = s->mixw_cb[j] + s->
f[i][0].score;
457 w_den[1][j] = s->mixw_cb[j] + s->
f[i][1].score;
458 w_den[2][j] = s->mixw_cb[j] + s->
f[i][2].score;
459 w_den[3][j] = s->mixw_cb[j] + s->
f[i][3].score;
460 w_den[4][j] = s->mixw_cb[j] + s->
f[i][4].score;
461 w_den[5][j] = s->mixw_cb[j] + s->
f[i][5].score;
464 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
465 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
466 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
467 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
468 pid_cw4 = s->mixw[i][s->
f[i][4].codeword];
469 pid_cw5 = s->mixw[i][s->
f[i][5].codeword];
471 for (l = j = 0; j < n_senone_active; j++) {
472 int n = senone_active[j] + l;
476 cw = pid_cw0[n/2] >> 4;
478 cw = pid_cw1[n/2] >> 4;
480 cw = pid_cw2[n/2] >> 4;
482 cw = pid_cw3[n/2] >> 4;
484 cw = pid_cw4[n/2] >> 4;
486 cw = pid_cw5[n/2] >> 4;
490 cw = pid_cw0[n/2] & 0x0f;
492 cw = pid_cw1[n/2] & 0x0f;
494 cw = pid_cw2[n/2] & 0x0f;
496 cw = pid_cw3[n/2] & 0x0f;
498 cw = pid_cw4[n/2] & 0x0f;
500 cw = pid_cw5[n/2] & 0x0f;
503 senone_scores[n] += tmp;
511 int16 *senone_scores, uint8 *senone_active,
512 int32 n_senone_active)
515 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3, *pid_cw4;
519 for (j = 0; j < 16; ++j) {
520 w_den[0][j] = s->mixw_cb[j] + s->
f[i][0].score;
521 w_den[1][j] = s->mixw_cb[j] + s->
f[i][1].score;
522 w_den[2][j] = s->mixw_cb[j] + s->
f[i][2].score;
523 w_den[3][j] = s->mixw_cb[j] + s->
f[i][3].score;
524 w_den[4][j] = s->mixw_cb[j] + s->
f[i][4].score;
527 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
528 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
529 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
530 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
531 pid_cw4 = s->mixw[i][s->
f[i][4].codeword];
533 for (l = j = 0; j < n_senone_active; j++) {
534 int n = senone_active[j] + l;
538 cw = pid_cw0[n/2] >> 4;
540 cw = pid_cw1[n/2] >> 4;
542 cw = pid_cw2[n/2] >> 4;
544 cw = pid_cw3[n/2] >> 4;
546 cw = pid_cw4[n/2] >> 4;
550 cw = pid_cw0[n/2] & 0x0f;
552 cw = pid_cw1[n/2] & 0x0f;
554 cw = pid_cw2[n/2] & 0x0f;
556 cw = pid_cw3[n/2] & 0x0f;
558 cw = pid_cw4[n/2] & 0x0f;
561 senone_scores[n] += tmp;
569 int16 *senone_scores, uint8 *senone_active,
570 int32 n_senone_active)
573 uint8 *pid_cw0, *pid_cw1, *pid_cw2, *pid_cw3;
577 for (j = 0; j < 16; ++j) {
578 w_den[0][j] = s->mixw_cb[j] + s->
f[i][0].score;
579 w_den[1][j] = s->mixw_cb[j] + s->
f[i][1].score;
580 w_den[2][j] = s->mixw_cb[j] + s->
f[i][2].score;
581 w_den[3][j] = s->mixw_cb[j] + s->
f[i][3].score;
584 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
585 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
586 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
587 pid_cw3 = s->mixw[i][s->
f[i][3].codeword];
589 for (l = j = 0; j < n_senone_active; j++) {
590 int n = senone_active[j] + l;
594 cw = pid_cw0[n/2] >> 4;
596 cw = pid_cw1[n/2] >> 4;
598 cw = pid_cw2[n/2] >> 4;
600 cw = pid_cw3[n/2] >> 4;
604 cw = pid_cw0[n/2] & 0x0f;
606 cw = pid_cw1[n/2] & 0x0f;
608 cw = pid_cw2[n/2] & 0x0f;
610 cw = pid_cw3[n/2] & 0x0f;
613 senone_scores[n] += tmp;
621 int16 *senone_scores, uint8 *senone_active,
622 int32 n_senone_active)
625 uint8 *pid_cw0, *pid_cw1, *pid_cw2;
629 for (j = 0; j < 16; ++j) {
630 w_den[0][j] = s->mixw_cb[j] + s->
f[i][0].score;
631 w_den[1][j] = s->mixw_cb[j] + s->
f[i][1].score;
632 w_den[2][j] = s->mixw_cb[j] + s->
f[i][2].score;
635 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
636 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
637 pid_cw2 = s->mixw[i][s->
f[i][2].codeword];
639 for (l = j = 0; j < n_senone_active; j++) {
640 int n = senone_active[j] + l;
644 cw = pid_cw0[n/2] >> 4;
646 cw = pid_cw1[n/2] >> 4;
648 cw = pid_cw2[n/2] >> 4;
652 cw = pid_cw0[n/2] & 0x0f;
654 cw = pid_cw1[n/2] & 0x0f;
656 cw = pid_cw2[n/2] & 0x0f;
659 senone_scores[n] += tmp;
667 int16 *senone_scores, uint8 *senone_active,
668 int32 n_senone_active)
671 uint8 *pid_cw0, *pid_cw1;
675 for (j = 0; j < 16; ++j) {
676 w_den[0][j] = s->mixw_cb[j] + s->
f[i][0].score;
677 w_den[1][j] = s->mixw_cb[j] + s->
f[i][1].score;
680 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
681 pid_cw1 = s->mixw[i][s->
f[i][1].codeword];
683 for (l = j = 0; j < n_senone_active; j++) {
684 int n = senone_active[j] + l;
688 cw = pid_cw0[n/2] >> 4;
690 cw = pid_cw1[n/2] >> 4;
694 cw = pid_cw0[n/2] & 0x0f;
696 cw = pid_cw1[n/2] & 0x0f;
699 senone_scores[n] += tmp;
707 int16 *senone_scores, uint8 *senone_active,
708 int32 n_senone_active)
715 for (j = 0; j < 16; ++j) {
716 w_den[j] = s->mixw_cb[j] + s->
f[i][0].score;
719 pid_cw0 = s->mixw[i][s->
f[i][0].codeword];
721 for (l = j = 0; j < n_senone_active; j++) {
722 int n = senone_active[j] + l;
726 cw = pid_cw0[n/2] >> 4;
730 cw = pid_cw0[n/2] & 0x0f;
733 senone_scores[n] += tmp;
741 int16 *senone_scores, uint8 *senone_active,
742 int32 n_senone_active)
746 for (l = j = 0; j < n_senone_active; j++) {
747 int n = senone_active[j] + l;
751 pid_cw = s->mixw[i][s->
f[i][0].codeword];
753 cw = pid_cw[n/2] >> 4;
755 cw = pid_cw[n/2] & 0x0f;
756 tmp = s->mixw_cb[cw] + s->
f[i][0].score;
757 for (k = 1; k < topn; ++k) {
758 pid_cw = s->mixw[i][s->
f[i][k].codeword];
760 cw = pid_cw[n/2] >> 4;
762 cw = pid_cw[n/2] & 0x0f;
764 s->mixw_cb[cw] + s->
f[i][k].score);
766 senone_scores[n] += tmp;
774 int16 *senone_scores, uint8 *senone_active, int32 n_senone_active)
778 return get_scores_4b_feat_6(s, i, senone_scores,
779 senone_active, n_senone_active);
781 return get_scores_4b_feat_5(s, i, senone_scores,
782 senone_active, n_senone_active);
784 return get_scores_4b_feat_4(s, i, senone_scores,
785 senone_active, n_senone_active);
787 return get_scores_4b_feat_3(s, i, senone_scores,
788 senone_active, n_senone_active);
790 return get_scores_4b_feat_2(s, i, senone_scores,
791 senone_active, n_senone_active);
793 return get_scores_4b_feat_1(s, i, senone_scores,
794 senone_active, n_senone_active);
796 return get_scores_4b_feat_any(s, i, topn, senone_scores,
797 senone_active, n_senone_active);
802 get_scores_4b_feat_all(
s2_semi_mgau_t * s,
int i,
int topn, int16 *senone_scores)
808 last_sen = s->n_sen & ~1;
809 while (j < last_sen) {
814 pid_cw = s->mixw[i][s->
f[i][0].codeword];
815 tmp0 = s->mixw_cb[pid_cw[j/2] & 0x0f] + s->
f[i][0].score;
816 tmp1 = s->mixw_cb[pid_cw[j/2] >> 4] + s->
f[i][0].score;
817 for (k = 1; k < topn; ++k) {
818 int32 w_den0, w_den1;
820 pid_cw = s->mixw[i][s->
f[i][k].codeword];
821 w_den0 = s->mixw_cb[pid_cw[j/2] & 0x0f] + s->
f[i][k].score;
822 w_den1 = s->mixw_cb[pid_cw[j/2] >> 4] + s->
f[i][k].score;
826 senone_scores[j++] += tmp0;
827 senone_scores[j++] += tmp1;
837 int16 *senone_scores,
838 uint8 *senone_active,
839 int32 n_senone_active,
840 mfcc_t ** featbuf, int32 frame,
845 int n_feat = s->g->
n_feat;
847 memset(senone_scores, 0, s->n_sen *
sizeof(*senone_scores));
853 for (i = 0; i < n_feat; ++i) {
855 if (frame >= ps_mgau_base(ps)->frame_idx) {
861 memcpy(s->
f[i], lastf[i],
sizeof(
vqFeature_t) * s->max_topn);
862 mgau_dist(s, frame, i, featbuf[i]);
867 get_scores_4b_feat_all(s, i, s->
topn_hist_n[topn_idx][i], senone_scores);
869 get_scores_4b_feat(s, i, s->
topn_hist_n[topn_idx][i], senone_scores,
870 senone_active, n_senone_active);
874 get_scores_8b_feat_all(s, i, s->
topn_hist_n[topn_idx][i], senone_scores);
876 get_scores_8b_feat(s, i, s->
topn_hist_n[topn_idx][i], senone_scores,
877 senone_active, n_senone_active);
890 int32 do_swap, do_mmap;
893 int n_feat = s->g->
n_feat;
895 int n_sen = bin_mdef_n_sen(mdef);
899 do_mmap = cmd_ln_boolean_r(s->config,
"-mmap");
901 if ((fp = fopen(file,
"rb")) == NULL)
904 E_INFO(
"Loading senones from dump file %s\n", file);
906 if (fread(&n,
sizeof(int32), 1, fp) != 1) {
907 E_ERROR_SYSTEM(
"Failed to read title size from %s", file);
912 if (n < 1 || n > 999) {
914 if (n < 1 || n > 999) {
915 E_ERROR(
"Title length %x in dump file %s out of range\n", n, file);
920 if (fread(line,
sizeof(
char), n, fp) != n) {
921 E_ERROR_SYSTEM(
"Cannot read title");
924 if (line[n - 1] !=
'\0') {
925 E_ERROR(
"Bad title in dump file\n");
928 E_INFO(
"%s\n", line);
931 if (fread(&n,
sizeof(n), 1, fp) != 1) {
932 E_ERROR_SYSTEM(
"Failed to read header size from %s", file);
935 if (do_swap) SWAP_INT32(&n);
936 if (fread(line,
sizeof(
char), n, fp) != n) {
937 E_ERROR_SYSTEM(
"Cannot read header");
940 if (line[n - 1] !=
'\0') {
941 E_ERROR(
"Bad header in dump file\n");
947 if (fread(&n,
sizeof(n), 1, fp) != 1) {
948 E_ERROR_SYSTEM(
"Failed to read header string size from %s", file);
951 if (do_swap) SWAP_INT32(&n);
954 if (fread(line,
sizeof(
char), n, fp) != n) {
955 E_ERROR_SYSTEM(
"Cannot read header");
959 if (!strncmp(line,
"feature_count ", strlen(
"feature_count "))) {
960 n_feat = atoi(line + strlen(
"feature_count "));
962 if (!strncmp(line,
"mixture_count ", strlen(
"mixture_count "))) {
963 n_density = atoi(line + strlen(
"mixture_count "));
965 if (!strncmp(line,
"model_count ", strlen(
"model_count "))) {
966 n_sen = atoi(line + strlen(
"model_count "));
968 if (!strncmp(line,
"cluster_count ", strlen(
"cluster_count "))) {
969 n_clust = atoi(line + strlen(
"cluster_count "));
971 if (!strncmp(line,
"cluster_bits ", strlen(
"cluster_bits "))) {
972 n_bits = atoi(line + strlen(
"cluster_bits "));
981 if (fread(&r,
sizeof(r), 1, fp) != 1) {
982 E_ERROR_SYSTEM(
"Cannot read #rows");
985 if (do_swap) SWAP_INT32(&r);
986 if (fread(&c,
sizeof(c), 1, fp) != 1) {
987 E_ERROR_SYSTEM(
"Cannot read #columns");
990 if (do_swap) SWAP_INT32(&c);
991 E_INFO(
"Rows: %d, Columns: %d\n", r, c);
994 if (n_feat != s->g->
n_feat) {
995 E_ERROR(
"Number of feature streams mismatch: %d != %d\n",
1000 E_ERROR(
"Number of densities mismatch: %d != %d\n",
1004 if (n_sen != s->n_sen) {
1005 E_ERROR(
"Number of senones mismatch: %d != %d\n",
1010 if (!((n_clust == 0) || (n_clust == 15) || (n_clust == 16))) {
1011 E_ERROR(
"Cluster count must be 0, 15, or 16\n");
1017 if (!((n_bits == 8) || (n_bits == 4))) {
1018 E_ERROR(
"Cluster count must be 4 or 8\n");
1023 E_INFO(
"Using memory-mapped I/O for senones\n");
1029 s->sendump_mmap = mmio_file_read(file);
1032 s->mixw_cb = ((uint8 *) mmio_file_ptr(s->sendump_mmap)) + offset;
1039 s->mixw_cb = ckd_calloc(1, n_clust);
1040 if (fread(s->mixw_cb, 1, n_clust, fp) != (
size_t) n_clust) {
1041 E_ERROR(
"Failed to read %d bytes from sendump\n", n_clust);
1048 if (s->sendump_mmap) {
1049 s->mixw = ckd_calloc_2d(n_feat, n_density,
sizeof(*s->mixw));
1050 for (n = 0; n < n_feat; n++) {
1053 step = (step + 1) / 2;
1054 for (i = 0; i < r; i++) {
1055 s->mixw[n][i] = ((uint8 *) mmio_file_ptr(s->sendump_mmap)) + offset;
1061 s->mixw = ckd_calloc_3d(n_feat, n_density, n_sen,
sizeof(***s->mixw));
1063 for (n = 0; n < n_feat; n++) {
1066 step = (step + 1) / 2;
1067 for (i = 0; i < r; i++) {
1068 if (fread(s->mixw[n][i],
sizeof(***s->mixw), step, fp)
1070 E_ERROR(
"Failed to read %d bytes from sendump\n", step);
1085 read_mixw(
s2_semi_mgau_t * s,
char const *file_name,
double SmoothMin)
1087 char **argname, **argval;
1090 int32 byteswap, chksum_present;
1099 E_INFO(
"Reading mixture weights file '%s'\n", file_name);
1101 if ((fp = fopen(file_name,
"rb")) == NULL)
1102 E_FATAL_SYSTEM(
"Failed to open mixture weights file '%s' for reading", file_name);
1105 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
1106 E_FATAL(
"Failed to read header from file '%s'\n", file_name);
1110 for (i = 0; argname[i]; i++) {
1111 if (strcmp(argname[i],
"version") == 0) {
1112 if (strcmp(argval[i], MGAU_MIXW_VERSION) != 0)
1113 E_WARN(
"Version mismatch(%s): %s, expecting %s\n",
1114 file_name, argval[i], MGAU_MIXW_VERSION);
1116 else if (strcmp(argname[i],
"chksum0") == 0) {
1120 bio_hdrarg_free(argname, argval);
1121 argname = argval = NULL;
1126 if ((bio_fread(&n_sen,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
1127 || (bio_fread(&n_feat,
sizeof(int32), 1, fp, byteswap, &chksum) !=
1129 || (bio_fread(&n_comp,
sizeof(int32), 1, fp, byteswap, &chksum) !=
1131 || (bio_fread(&n,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)) {
1132 E_FATAL(
"bio_fread(%s) (arraysize) failed\n", file_name);
1134 if (n_feat != s->g->
n_feat)
1135 E_FATAL(
"#Features streams(%d) != %d\n", n_feat, s->g->
n_feat);
1136 if (n != n_sen * n_feat * n_comp) {
1138 (
"%s: #float32s(%d) doesn't match header dimensions: %d x %d x %d\n",
1139 file_name, i, n_sen, n_feat, n_comp);
1148 s->mixw = ckd_calloc_3d(n_feat, s->g->
n_density, n_sen,
sizeof(***s->mixw));
1151 pdf = (float32 *) ckd_calloc(n_comp,
sizeof(float32));
1155 for (i = 0; i < n_sen; i++) {
1156 for (f = 0; f < n_feat; f++) {
1157 if (bio_fread((
void *) pdf,
sizeof(float32),
1158 n_comp, fp, byteswap, &chksum) != n_comp) {
1159 E_FATAL(
"bio_fread(%s) (arraydata) failed\n", file_name);
1163 if (vector_sum_norm(pdf, n_comp) <= 0.0)
1165 vector_floor(pdf, n_comp, SmoothMin);
1166 vector_sum_norm(pdf, n_comp);
1169 for (c = 0; c < n_comp; c++) {
1172 qscr = -logmath_log(s->lmath_8b, pdf[c]);
1175 s->mixw[f][c][i] = qscr;
1180 E_WARN(
"Weight normalization failed for %d mixture weights components\n", n_err);
1185 bio_verify_chksum(fp, byteswap, chksum);
1187 if (fread(&eofchk, 1, 1, fp) == 1)
1188 E_FATAL(
"More data than expected in %s\n", file_name);
1192 E_INFO(
"Read %d x %d x %d mixture weights\n", n_sen, n_feat, n_comp);
1198 split_topn(
char const *str, uint8 *out,
int nfeat)
1200 char *topn_list = ckd_salloc(str);
1207 while (i < nfeat && (cc = strchr(c,
',')) != NULL) {
1210 if (out[i] > maxn) maxn = out[i];
1214 if (i < nfeat && *c !=
'\0') {
1216 if (out[i] > maxn) maxn = out[i];
1222 ckd_free(topn_list);
1228 s2_semi_mgau_init(
acmod_t *acmod)
1232 char const *sendump_path;
1236 s = ckd_calloc(1,
sizeof(*s));
1237 s->config = acmod->
config;
1239 s->lmath = logmath_retain(acmod->
lmath);
1242 if (s->lmath_8b == NULL)
1245 if (logmath_get_width(s->lmath_8b) != 1) {
1246 E_ERROR(
"Log base %f is too small to represent add table in 8 bits\n",
1247 logmath_get_base(s->lmath_8b));
1252 if ((s->g =
gauden_init(cmd_ln_str_r(s->config,
"_mean"),
1253 cmd_ln_str_r(s->config,
"_var"),
1254 cmd_ln_float32_r(s->config,
"-varfloor"),
1255 s->lmath)) == NULL) {
1256 E_ERROR(
"Failed to read means and variances\n");
1267 if (n_feat != feat_dimension1(acmod->
fcb)) {
1268 E_ERROR(
"Number of streams does not match: %d != %d\n",
1269 n_feat, feat_dimension1(acmod->
fcb));
1272 for (i = 0; i < n_feat; ++i) {
1273 if (s->g->
featlen[i] != feat_dimension2(acmod->
fcb, i)) {
1274 E_ERROR(
"Dimension of stream %d does not match: %d != %d\n",
1275 i, s->g->
featlen[i], feat_dimension2(acmod->
fcb, i));
1280 if ((sendump_path = cmd_ln_str_r(s->config,
"_sendump"))) {
1281 if (read_sendump(s, acmod->
mdef, sendump_path) < 0) {
1286 if (read_mixw(s, cmd_ln_str_r(s->config,
"_mixw"),
1287 cmd_ln_float32_r(s->config,
"-mixwfloor")) < 0) {
1291 s->ds_ratio = cmd_ln_int32_r(s->config,
"-ds");
1294 s->topn_beam = ckd_calloc(n_feat,
sizeof(*s->topn_beam));
1295 s->max_topn = cmd_ln_int32_r(s->config,
"-topn");
1296 split_topn(cmd_ln_str_r(s->config,
"-topn_beam"), s->topn_beam, n_feat);
1297 E_INFO(
"Maximum top-N: %d ", s->max_topn);
1298 E_INFOCONT(
"Top-N beams:");
1299 for (i = 0; i < n_feat; ++i) {
1300 E_INFOCONT(
" %d", s->topn_beam[i]);
1305 s->
n_topn_hist = cmd_ln_int32_r(s->config,
"-pl_window") + 2;
1307 ckd_calloc_3d(s->
n_topn_hist, n_feat, s->max_topn,
1313 for (j = 0; j < n_feat; ++j) {
1315 for (k = 0; k < s->max_topn; ++k) {
1316 s->
topn_hist[i][j][k].score = WORST_DIST;
1323 ps->
vt = &s2_semi_mgau_funcs;
1326 s2_semi_mgau_free(ps_mgau_base(s));
1331 s2_semi_mgau_mllr_transform(
ps_mgau_t *ps,
1343 logmath_free(s->lmath);
1344 logmath_free(s->lmath_8b);
1345 if (s->sendump_mmap) {
1346 ckd_free_2d(s->mixw);
1347 mmio_file_unmap(s->sendump_mmap);
1350 ckd_free_3d(s->mixw);
1352 ckd_free(s->mixw_cb);
1355 ckd_free(s->topn_beam);
int32 n_density
Number gaussian densities in each codebook-feature stream.
void gauden_free(gauden_t *g)
Release memory allocated by gauden_init.
mfcc_t *** det
log(determinant) for each variance vector; actually, log(sqrt(2*pi*det))
logmath_t * lmath
Log-math computation.
int n_topn_hist
Number of past frames tracked.
vqFeature_t *** topn_hist
Top-N scores and codewords for past frames.
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).
gauden_t * gauden_init(char const *meanfile, char const *varfile, float32 varfloor, logmath_t *lmath)
Read mixture gaussian codebooks from the given files.
cmd_ln_t * config
Configuration.
int32 * featlen
feature length for each feature
#define GMMSUB(a, b)
Subtract GMM component b (assumed to be positive) and saturate.
int32 n_mgau
Number codebooks.
Feature space linear transform structure.
#define SENSCR_SHIFT
Shift count for senone scores.
mfcc_t **** mean
mean[codebook][feature][codeword] vector
feat_t * fcb
Dynamic feature computation.
int32 n_feat
Number feature streams in each codebook.
uint8 ** topn_hist_n
Variable top-N for past frames.
ps_mgaufuncs_t * vt
vtable of mgau functions.
LOGMATH_INLINE int fast_logmath_add(logmath_t *lmath, int mlx, int mly)
Quickly log-add two negated log probabilities.
bin_mdef_t * mdef
Model definition.
#define MAX_NEG_ASCR
Maximum negated acoustic score value.
vqFeature_t ** f
Topn-N for currently scoring frame.
#define MAX_NEG_MIXW
Maximum negated mixture weight value.
Acoustic model structure.
mfcc_t **** var
like mean; diagonal covariance vector only
Common code shared between SC and PTM (tied-state) models.