📄 word_fsg.c
字号:
s2_fsg_trans_t *trans; word_fsg_t *cfsg; /* "Compiled" FSG structure */ char *wordptr[WORD_FSG_MAX_WORDPTR]; /* ptrs to words in an input line */ int32 lineno; int32 n, i, j; float32 p; lineno = 0; /* Scan upto FSG_BEGIN header */ for (;;) { n = nextline_str2words(fp, &lineno, wordptr, WORD_FSG_MAX_WORDPTR); if (n < 0) { E_ERROR("%s declaration missing\n", WORD_FSG_BEGIN_DECL); return NULL; } if ((strcmp(wordptr[0], WORD_FSG_BEGIN_DECL) == 0) || (strcmp(wordptr[0], WORD_FST_BEGIN_DECL) == 0)) { if (n > 2) { E_ERROR("Line[%d]: malformed FSG_BEGIN delcaration\n", lineno); return NULL; } break; } } /* FSG_BEGIN found; note FSG name */ fsg = (s2_fsg_t *) ckd_calloc(1, sizeof(s2_fsg_t)); fsg->name = (n == 2) ? ckd_salloc(wordptr[1]) : NULL; fsg->trans_list = NULL; /* Read #states */ n = nextline_str2words(fp, &lineno, wordptr, WORD_FSG_MAX_WORDPTR); if ((n != 2) || ((strcmp(wordptr[0], WORD_FSG_N_DECL) != 0) && (strcmp(wordptr[0], WORD_FSG_NUM_STATES_DECL) != 0)) || (sscanf(wordptr[1], "%d", &(fsg->n_state)) != 1) || (fsg->n_state <= 0)) { E_ERROR ("Line[%d]: #states declaration line missing or malformed\n", lineno); goto parse_error; } /* Read start state */ n = nextline_str2words(fp, &lineno, wordptr, WORD_FSG_MAX_WORDPTR); if ((n != 2) || ((strcmp(wordptr[0], WORD_FSG_S_DECL) != 0) && (strcmp(wordptr[0], WORD_FSG_START_STATE_DECL) != 0)) || (sscanf(wordptr[1], "%d", &(fsg->start_state)) != 1) || (fsg->start_state < 0) || (fsg->start_state >= fsg->n_state)) { E_ERROR ("Line[%d]: start state declaration line missing or malformed\n", lineno); goto parse_error; } /* Read final state */ n = nextline_str2words(fp, &lineno, wordptr, WORD_FSG_MAX_WORDPTR); if ((n != 2) || ((strcmp(wordptr[0], WORD_FSG_F_DECL) != 0) && (strcmp(wordptr[0], WORD_FSG_FINAL_STATE_DECL) != 0)) || (sscanf(wordptr[1], "%d", &(fsg->final_state)) != 1) || (fsg->final_state < 0) || (fsg->final_state >= fsg->n_state)) { E_ERROR ("Line[%d]: final state declaration line missing or malformed\n", lineno); goto parse_error; } /* Read transitions */ for (;;) { n = nextline_str2words(fp, &lineno, wordptr, WORD_FSG_MAX_WORDPTR); if (n <= 0) { E_ERROR("Line[%d]: transition or FSG_END statement expected\n", lineno); goto parse_error; } if ((strcmp(wordptr[0], WORD_FSG_END_DECL) == 0) || (strcmp(wordptr[0], WORD_FST_END_DECL) == 0)) { break; } if ((strcmp(wordptr[0], WORD_FSG_T_DECL) == 0) || (strcmp(wordptr[0], WORD_FSG_TRANSITION_DECL) == 0)) { if (((n != 4) && (n != 5)) || (sscanf(wordptr[1], "%d", &i) != 1) || (sscanf(wordptr[2], "%d", &j) != 1) || (sscanf(wordptr[3], "%f", &p) != 1) || (i < 0) || (i >= fsg->n_state) || (j < 0) || (j >= fsg->n_state) || (p <= 0.0) || (p > 1.0)) { E_ERROR ("Line[%d]: transition spec malformed; Expecting: from-state to-state trans-prob [word]\n", lineno); goto parse_error; } } else { E_ERROR("Line[%d]: transition or FSG_END statement expected\n", lineno); goto parse_error; } /* Add transition to fsg */ trans = (s2_fsg_trans_t *) ckd_calloc(1, sizeof(s2_fsg_trans_t)); trans->from_state = i; trans->to_state = j; trans->prob = p; trans->word = (n > 4) ? ckd_salloc(wordptr[4]) : NULL; trans->next = fsg->trans_list; fsg->trans_list = trans; } cfsg = word_fsg_load(fsg, use_altpron, use_filler, silprob, fillprob, lw); s2_fsg_free(fsg); return cfsg; parse_error: s2_fsg_free(fsg); return NULL;}word_fsg_t *word_fsg_readfile(char *file, boolean use_altpron, boolean use_filler, float32 silprob, float32 fillprob, float32 lw){ FILE *fp; word_fsg_t *fsg; E_INFO ("Reading FSG file '%s' (altpron=%d, filler=%d, lw=%.2f, silprob=%.2e, fillprob=%.2e)\n", file, use_altpron, use_filler, lw, silprob, fillprob); if ((fp = fopen(file, "r")) == NULL) { E_ERROR("fopen(%s,r) failed\n", file); return NULL; } fsg = word_fsg_read(fp, use_altpron, use_filler, silprob, fillprob, lw); fclose(fp); return fsg;}voidword_fsg_free(word_fsg_t * fsg){ int32 i, j; gnode_t *gn; word_fsglink_t *tl; for (i = 0; i < fsg->n_state; i++) { for (j = 0; j < fsg->n_state; j++) { /* Free all non-null transitions between states i and j */ for (gn = fsg->trans[i][j]; gn; gn = gnode_next(gn)) { tl = (word_fsglink_t *) gnode_ptr(gn); ckd_free((void *) tl); } glist_free(fsg->trans[i][j]); /* Free any null transition i->j */ ckd_free((void *) fsg->null_trans[i][j]); } } ckd_free_2d((void **) fsg->trans); ckd_free_2d((void **) fsg->null_trans); ckd_free((void *) fsg->name); if (fsg->lc) ckd_free_2d((void **) fsg->lc); if (fsg->rc) ckd_free_2d((void **) fsg->rc); ckd_free((void *) fsg);}voidword_fsg_write(word_fsg_t * fsg, FILE * fp){ int32 i, j; gnode_t *gn; word_fsglink_t *tl;#ifdef _WIN32_WCE DWORD tp = GetTickCount();#else time_t tp = time(NULL);#endif assert(fsg); if (tp > 0) {#ifdef _WIN32_WCE fprintf(fp, "%c WORD-FSG; %d\n", WORD_FSG_COMMENT_CHAR, tp); /* FIXME: Totally wrong, but I have no idea how to get the time on WinCE. */#else fprintf(fp, "%c WORD-FSG; %s\n", WORD_FSG_COMMENT_CHAR, ctime(&tp));#endif } else fprintf(fp, "%c WORD-FSG\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%s\n", WORD_FSG_BEGIN_DECL); fprintf(fp, "%c #states\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%s %d\n", WORD_FSG_NUM_STATES_DECL, fsg->n_state); fprintf(fp, "%c start-state\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%s %d\n", WORD_FSG_START_STATE_DECL, fsg->start_state); fprintf(fp, "%c final-state\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%s %d\n", WORD_FSG_FINAL_STATE_DECL, fsg->final_state); fprintf(fp, "%c transitions\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%c from-state to-state logs2prob*lw word-ID\n", WORD_FSG_COMMENT_CHAR); for (i = 0; i < fsg->n_state; i++) { for (j = 0; j < fsg->n_state; j++) { /* Print non-null transitions */ for (gn = fsg->trans[i][j]; gn; gn = gnode_next(gn)) { tl = (word_fsglink_t *) gnode_ptr(gn); fprintf(fp, "%c %d %d %d %d\n", WORD_FSG_COMMENT_CHAR, tl->from_state, tl->to_state, tl->logs2prob, tl->wid); fprintf(fp, "%s %d %d %.3e %s\n", WORD_FSG_TRANSITION_DECL, tl->from_state, tl->to_state, EXP(tl->logs2prob / fsg->lw), (tl->wid < 0) ? "" : kb_get_word_str(tl->wid)); } /* Print null transitions */ tl = fsg->null_trans[i][j]; if (tl) { fprintf(fp, "%c %d %d %d\n", WORD_FSG_COMMENT_CHAR, tl->from_state, tl->to_state, tl->logs2prob); fprintf(fp, "%s %d %d %.3e\n", WORD_FSG_TRANSITION_DECL, tl->from_state, tl->to_state, EXP(tl->logs2prob / fsg->lw)); } } } /* Print lc/rc vectors */ if (fsg->lc && fsg->rc) { for (i = 0; i < fsg->n_state; i++) { fprintf(fp, "%c LC[%d]:", WORD_FSG_COMMENT_CHAR, i); for (j = 0; fsg->lc[i][j] >= 0; j++) fprintf(fp, " %s", phone_from_id(fsg->lc[i][j])); fprintf(fp, "\n"); fprintf(fp, "%c RC[%d]:", WORD_FSG_COMMENT_CHAR, i); for (j = 0; fsg->rc[i][j] >= 0; j++) fprintf(fp, " %s", phone_from_id(fsg->rc[i][j])); fprintf(fp, "\n"); } } fprintf(fp, "%c\n", WORD_FSG_COMMENT_CHAR); fprintf(fp, "%s\n", WORD_FSG_END_DECL); fflush(fp);}voidword_fsg_writefile(word_fsg_t * fsg, char *file){ FILE *fp; assert(fsg); E_INFO("Writing FSG file '%s'\n", file); if ((fp = fopen(file, "w")) == NULL) { E_ERROR("fopen(%s,r) failed\n", file); return; } word_fsg_write(fsg, fp); fclose(fp);}int32word_fsg_set_start_state(word_fsg_t * fsg, int32 state){ int32 prev; if ((!fsg) || (state < 0) || (state >= fsg->n_state)) return -1; prev = fsg->start_state; fsg->start_state = state; return prev;}int32word_fsg_set_final_state(word_fsg_t * fsg, int32 state){ int32 prev; if ((!fsg) || (state < 0) || (state >= fsg->n_state)) return -1; prev = fsg->final_state; fsg->final_state = state; return prev;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -