⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bin_mdef.c

📁 WinCE平台上的语音识别程序
💻 C
📖 第 1 页 / 共 2 页
字号:
        for (i = 0; i < m->n_cd_tree; ++i) {            SWAP_INT16(&m->cd_tree[i].ctx);            SWAP_INT16(&m->cd_tree[i].n_down);            SWAP_INT32(&m->cd_tree[i].c.down);        }    }    m->phone = (mdef_entry_t *) (m->cd_tree + m->n_cd_tree);    if (swap) {        for (i = 0; i < m->n_phone; ++i) {            SWAP_INT32(&m->phone[i].ssid);            SWAP_INT32(&m->phone[i].tmat);        }    }    sseq_size = (int32 *) (m->phone + m->n_phone);    if (swap)        SWAP_INT32(sseq_size);    m->sseq = ckd_calloc(m->n_sseq, sizeof(*m->sseq));    m->sseq[0] = (s3senid_t *) (sseq_size + 1);    if (swap) {        for (i = 0; i < *sseq_size; ++i)            SWAP_INT16(m->sseq[0] + i);    }    if (m->n_emit_state) {        for (i = 1; i < m->n_sseq; ++i)            m->sseq[i] = m->sseq[0] + i * m->n_emit_state;    }    else {        m->sseq_len = (int8 *) (m->sseq[0] + *sseq_size);        for (i = 1; i < m->n_sseq; ++i)            m->sseq[i] = m->sseq[i - 1] + m->sseq_len[i - 1];    }    /* Now build the CD-to-CI mappings using the senone sequences.     * This is the only really accurate way to do it, though it is     * still inaccurate in the case of heterogeneous topologies or     * cross-state tying. */    m->cd2cisen = (s3senid_t *) ckd_malloc(m->n_sen * sizeof(s3senid_t));    m->sen2cimap = (s3cipid_t *) ckd_malloc(m->n_sen * sizeof(s3cipid_t));    /* Default mappings (identity, none) */    for (i = 0; i < m->n_ci_sen; ++i)        m->cd2cisen[i] = i;    for (; i < m->n_sen; ++i)        m->cd2cisen[i] = BAD_S3SENID;    for (i = 0; i < m->n_sen; ++i)        m->sen2cimap[i] = BAD_S3CIPID;    for (i = 0; i < m->n_phone; ++i) {        int32 j, ssid = m->phone[i].ssid;        for (j = 0; j < bin_mdef_n_emit_state_phone(m, i); ++j) {            s3senid_t s = bin_mdef_sseq2sen(m, ssid, j);            s3cipid_t ci = bin_mdef_pid2ci(m, i);            /* Take the first one and warn if we have cross-state tying. */            if (m->sen2cimap[s] == BAD_S3CIPID)                m->sen2cimap[s] = ci;            if (m->sen2cimap[s] != ci)                E_WARN                    ("Senone %d is shared between multiple base phones\n",                     s);            if (j > bin_mdef_n_emit_state_phone(m, ci))                E_WARN("CD phone %d has fewer states than CI phone %d\n",                       i, ci);            else                m->cd2cisen[s] =                    bin_mdef_sseq2sen(m, m->phone[ci].ssid, j);        }    }    /* Set the silence phone. */    m->sil = bin_mdef_ciphone_id(m, S3_SILENCE_CIPHONE);    E_INFO        ("%d CI-phone, %d CD-phone, %d emitstate/phone, %d CI-sen, %d Sen, %d Sen-Seq\n",         m->n_ciphone, m->n_phone - m->n_ciphone, m->n_emit_state,         m->n_ci_sen, m->n_sen, m->n_sseq);    m->alloc_mode = BIN_MDEF_IN_MEMORY;    return m;}intbin_mdef_write(bin_mdef_t * m, const char *filename){    FILE *fh;    int32 val, i;    if ((fh = fopen(filename, "wb")) == NULL)        return -1;    /* Byteorder marker. */    val = BIN_MDEF_NATIVE_ENDIAN;    fwrite(&val, 1, 4, fh);    /* Version. */    val = BIN_MDEF_FORMAT_VERSION;    fwrite(&val, 1, sizeof(val), fh);    /* Round the format descriptor size up to a 4-byte boundary. */    val = ((sizeof(format_desc) + 3) & ~3);    fwrite(&val, 1, sizeof(val), fh);    fwrite(format_desc, 1, sizeof(format_desc), fh);    /* Pad it with zeros. */    i = 0;    fwrite(&i, 1, val - sizeof(format_desc), fh);    /* Binary header things. */    fwrite(&m->n_ciphone, 4, 1, fh);    fwrite(&m->n_phone, 4, 1, fh);    fwrite(&m->n_emit_state, 4, 1, fh);    fwrite(&m->n_ci_sen, 4, 1, fh);    fwrite(&m->n_sen, 4, 1, fh);    fwrite(&m->n_tmat, 4, 1, fh);    fwrite(&m->n_sseq, 4, 1, fh);    fwrite(&m->n_ctx, 4, 1, fh);    fwrite(&m->n_cd_tree, 4, 1, fh);    /* Write this as a 32-bit value to preserve alignment for the     * non-mmap case (we want things aligned both from the     * beginning of the file and the beginning of the phone     * strings). */    val = m->sil;    fwrite(&val, 4, 1, fh);    /* Phone strings. */    for (i = 0; i < m->n_ciphone; ++i)        fwrite(m->ciname[i], 1, strlen(m->ciname[i]) + 1, fh);    /* Pad with zeros. */    val = (ftell(fh) + 3) & ~3;    i = 0;    fwrite(&i, 1, val - ftell(fh), fh);    /* Write CD-tree */    fwrite(m->cd_tree, sizeof(*m->cd_tree), m->n_cd_tree, fh);    /* Write phones */    fwrite(m->phone, sizeof(*m->phone), m->n_phone, fh);    if (m->n_emit_state) {        /* Write size of sseq */        val = m->n_sseq * m->n_emit_state;        fwrite(&val, 4, 1, fh);        /* Write sseq */        fwrite(m->sseq[0], sizeof(s3senid_t), m->n_sseq * m->n_emit_state,               fh);    }    else {        int32 n;        /* Calcluate size of sseq */        n = 0;        for (i = 0; i < m->n_sseq; ++i)            n += m->sseq_len[i];        /* Write size of sseq */        fwrite(&n, 4, 1, fh);        /* Write sseq */        fwrite(m->sseq[0], sizeof(s3senid_t), n, fh);        /* Write sseq_len */        fwrite(m->sseq_len, 1, m->n_sseq, fh);    }    fclose(fh);    return 0;}intbin_mdef_write_text(bin_mdef_t * m, const char *filename){    FILE *fh;    int p, i, n_total_state;    if (strcmp(filename, "-") == 0)        fh = stdout;    else {        if ((fh = fopen(filename, "w")) == NULL)            return -1;    }    fprintf(fh, "0.3\n");    fprintf(fh, "%d n_base\n", m->n_ciphone);    fprintf(fh, "%d n_tri\n", m->n_phone - m->n_ciphone);    if (m->n_emit_state)        n_total_state = m->n_phone * (m->n_emit_state + 1);    else {        n_total_state = 0;        for (i = 0; i < m->n_phone; ++i)            n_total_state += m->sseq_len[m->phone[i].ssid] + 1;    }    fprintf(fh, "%d n_state_map\n", n_total_state);    fprintf(fh, "%d n_tied_state\n", m->n_sen);    fprintf(fh, "%d n_tied_ci_state\n", m->n_ci_sen);    fprintf(fh, "%d n_tied_tmat\n", m->n_tmat);    fprintf(fh, "#\n# Columns definitions\n");    fprintf(fh, "#%4s %3s %3s %1s %6s %4s %s\n",            "base", "lft", "rt", "p", "attrib", "tmat",            "     ... state id's ...");    for (p = 0; p < m->n_ciphone; p++) {        int n_state;        fprintf(fh, "%5s %3s %3s %1s", m->ciname[p], "-", "-", "-");        if (bin_mdef_is_fillerphone(m, p))            fprintf(fh, " %6s", "filler");        else            fprintf(fh, " %6s", "n/a");        fprintf(fh, " %4d", m->phone[p].tmat);        if (m->n_emit_state)            n_state = m->n_emit_state;        else            n_state = m->sseq_len[m->phone[p].ssid];        for (i = 0; i < n_state; i++) {            fprintf(fh, " %6u", m->sseq[m->phone[p].ssid][i]);        }        fprintf(fh, " N\n");    }    for (; p < m->n_phone; p++) {        int n_state;        fprintf(fh, "%5s %3s %3s %c",                m->ciname[m->phone[p].info.cd.ctx[0]],                m->ciname[m->phone[p].info.cd.ctx[1]],                m->ciname[m->phone[p].info.cd.ctx[2]],                (WPOS_NAME)[m->phone[p].info.cd.wpos]);        if (bin_mdef_is_fillerphone(m, p))            fprintf(fh, " %6s", "filler");        else            fprintf(fh, " %6s", "n/a");        fprintf(fh, " %4d", m->phone[p].tmat);        if (m->n_emit_state)            n_state = m->n_emit_state;        else            n_state = m->sseq_len[m->phone[p].ssid];        for (i = 0; i < n_state; i++) {            fprintf(fh, " %6u", m->sseq[m->phone[p].ssid][i]);        }        fprintf(fh, " N\n");    }    if (strcmp(filename, "-") != 0)        fclose(fh);    return 0;}s3cipid_tbin_mdef_ciphone_id(bin_mdef_t * m, const char *ciphone){    int low, mid, high;    /* Exact binary search on m->ciphone */    low = 0;    high = m->n_ciphone;    while (low < high) {        int c;        mid = (low + high) / 2;        c = strcmp(ciphone, m->ciname[mid]);        if (c == 0)            return mid;        else if (c > 0)            low = mid + 1;        else if (c < 0)            high = mid;    }    return BAD_S3CIPID;}const char *bin_mdef_ciphone_str(bin_mdef_t * m, int32 ci){    assert(m != NULL);    assert(ci < m->n_ciphone);    return m->ciname[ci];}s3pid_tbin_mdef_phone_id(bin_mdef_t * m, int32 ci, int32 lc, int32 rc, int32 wpos){    cd_tree_t *cd_tree;    int level, max;    s3cipid_t ctx[4];    assert(m);    assert((ci >= 0) && (ci < m->n_ciphone));    assert((lc >= 0) && (lc < m->n_ciphone));    assert((rc >= 0) && (rc < m->n_ciphone));    assert((wpos >= 0) && (wpos < N_WORD_POSN));    /* Create a context list, mapping fillers to silence. */    ctx[0] = wpos;    ctx[1] = ci;    ctx[2] = (IS_S3CIPID(m->sil)              && m->phone[lc].info.ci.filler) ? m->sil : lc;    ctx[3] = (IS_S3CIPID(m->sil)              && m->phone[rc].info.ci.filler) ? m->sil : rc;    /* Walk down the cd_tree. */    cd_tree = m->cd_tree;    level = 0;                  /* What level we are on. */    max = N_WORD_POSN;          /* Number of nodes on this level. */    while (level < 4) {        int i;#if 0        E_INFO("Looking for context %d=%s in %d at %d\n",               ctx[level], m->ciname[ctx[level]],               max, cd_tree - m->cd_tree);#endif        for (i = 0; i < max; ++i) {#if 0            E_INFO("Look at context %d=%s at %d\n",                   cd_tree[i].ctx,                   m->ciname[cd_tree[i].ctx], cd_tree + i - m->cd_tree);#endif            if (cd_tree[i].ctx == ctx[level])                break;        }        if (i == max)            return BAD_S3PID;#if 0        E_INFO("Found context %d=%s at %d, n_down=%d, down=%d\n",               ctx[level], m->ciname[ctx[level]],               cd_tree + i - m->cd_tree,               cd_tree[i].n_down, cd_tree[i].c.down);#endif        /* Leaf node, stop here. */        if (cd_tree[i].n_down == 0)            return cd_tree[i].c.pid;        /* Go down one level. */        max = cd_tree[i].n_down;        cd_tree = m->cd_tree + cd_tree[i].c.down;        ++level;    }    /* We probably shouldn't get here. */    return BAD_S3PID;}int32bin_mdef_phone_str(bin_mdef_t * m, s3pid_t pid, char *buf){    char *wpos_name;    assert(m);    assert((pid >= 0) && (pid < m->n_phone));    wpos_name = WPOS_NAME;    buf[0] = '\0';    if (pid < m->n_ciphone)        sprintf(buf, "%s", bin_mdef_ciphone_str(m, (s3cipid_t) pid));    else {        sprintf(buf, "%s %s %s %c",                bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[0]),                bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[1]),                bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[2]),                wpos_name[m->phone[pid].info.cd.wpos]);    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -