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

📄 dict.c

📁 WinCE平台上的语音识别程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- *//* ==================================================================== * Copyright (c) 1999-2001 Carnegie Mellon University.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * This work was supported in part by funding from the Defense Advanced  * Research Projects Agency and the National Science Foundation of the  * United States of America, and the CMU Sphinx Speech Consortium. * * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ==================================================================== * *//*  * HISTORY *  * 05-Nov-98  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 		dict_load now terminates program if input dictionary  *              contains errors. *  * 21-Nov-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 		Bugfix: Noise dictionary was not being considered in figuring *              dictionary size. *  * 18-Nov-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 		Added ability to modify pronunciation of an existing word in *              dictionary (in dict_add_word()). *  * 10-Aug-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University *		Added check for word already existing in dictionary in  *              dict_add_word(). *  * 27-May-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 		Included Bob Brennan's personaldic handling (similar to  *              oovdic). *  * 11-Apr-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University *		Made changes to replace_dict_entry to handle the addition of * 		alternative pronunciations (linking in alt, wid, fwid fields). *  * 02-Apr-97  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 		Caused a fatal error if max size exceeded, instead of realloc. *  * 08-Dec-95  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 	Added function dict_write_oovdict(). *  * 06-Dec-95  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie-Mellon University * 	Added functions dict_next_alt() and dict_pron(). *  * Revision 8.5  94/10/11  12:32:03  rkm * Minor changes. *  * Revision 8.4  94/07/29  11:49:59  rkm * Changed handling of OOV subdictionary (no longer alternatives to <UNK>). * Added placeholders for dynamic addition of words to dictionary. * Added dict_add_word () for adding new words to dictionary. *  * Revision 8.3  94/04/14  15:08:31  rkm * Added function dictid_to_str(). *  * Revision 8.2  94/04/14  14:34:11  rkm * Added OOV words sub-dictionary. *  * Revision 8.1  94/02/15  15:06:26  rkm * Basically the same as in v7; includes multiple start symbols for * the LISTEN project. *  * 11-Feb-94  M K Ravishankar (rkm) at Carnegie-Mellon University * 	Added multiple start symbols for the LISTEN project. *  *  9-Sep-92  Fil Alleva (faa) at Carnegie-Mellon University *	Added special silences for start_sym and end_sym. *	These special silences *	(SILb and SILe) are CI models and as such they create a new context, *	however since no triphones model these contexts explicity they are *	backed off to silence, which is the desired context. Therefore no *	special measures are take inside the decoder to handle these *	special silences. * 14-Oct-92  Eric Thayer (eht) at Carnegie Mellon University *	added Ravi's formal declarations for dict_to_id() so int32 -> pointer *	problem doesn't happen on DEC Alpha * 14-Oct-92  Eric Thayer (eht) at Carnegie Mellon University *	added Ravi's changes to make calls into hash.c work properly on Alpha *	 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <cmd_ln.h>#include <ckd_alloc.h>#include <pio.h>#include <hash_table.h>#include <err.h>#include "s2types.h"#include "strfuncs.h"#include "basic_types.h"#include "list.h"#include "phone.h"#include "dict.h"#include "search_const.h"#include "lmclass.h"#include "lm_3g.h"#include "msd.h"#include "kb.h"#ifdef DEBUG#define DFPRINTF(x)		fprintf x#else#define DFPRINTF(x)#endif#define QUIT(x)		{fprintf x; exit(-1);}extern int32 use_noise_words;static void buildEntryTable(list_t * list, int32 *** table_p);static void buildExitTable(list_t * list, int32 *** table_p,                           int32 *** permuTab_p, int32 ** sizeTab_p);static int32 addToLeftContextTable(char *diphone);static int32 addToRightContextTable(char *diphone);static void recordMissingTriphone(char *triphoneStr);static dict_entry_t *_new_dict_entry(char *word_str,                                     char *pronoun_str,                                     int32 use_context);static void _dict_list_add(dictT * dict, dict_entry_t * entry);static void dict_load(dictT * dict, char *filename, int32 * word_id,                      int32 use_context);static hash_table_t *mtpHT;     /* Missing triphone hash table */static glist_t mtpList;static hash_table_t *lcHT;      /* Left context hash table */static list_t lcList;static int32 **lcFwdTable;static int32 **lcBwdTable;static int32 **lcBwdPermTable;static int32 *lcBwdSizeTable;static hash_table_t *rcHT;      /* Right context hash table */static list_t rcList;static int32 **rcFwdTable;static int32 **rcFwdPermTable;static int32 **rcBwdTable;static int32 *rcFwdSizeTable;/* First and last OOVs loaded DURING INITIALIZATION */static int32 first_initial_oov, last_initial_oov;/* Placeholders for dynamically added new words, OOVs */static int32 initial_dummy;     /* 1st placeholder for dynamic OOVs after initialization */static int32 first_dummy;       /* 1st dummy available for dynamic OOVs at any time */static int32 last_dummy;        /* last dummy available for dynamic OOVs */#define MAX_PRONOUN_LEN 	150static int32get_dict_size(char *file){    FILE *fp;    char line[1024];    int32 n;    fp = myfopen(file, "r");    for (n = 0;; n++)        if (fgets(line, sizeof(line), fp) == NULL)            break;    fclose(fp);    return n;}int32dict_read(dictT * dict, char *filename, /* Main dict file */          char *n_filename,     /* Noise dict file */          int32 use_context)/*------------------------------------------------------------* * read in the dict file filename *------------------------------------------------------------*/{    int32 retval = 0;    int32 word_id = 0, i, j;    dict_entry_t *entry;    int32 max_new_oov;    char *oovdic;    char *personalDic;    char *startsym_file;    /*     * Find size of dictionary and set hash and list table size hints.     * (Otherwise, the simple-minded PC malloc library goes berserk.)     */    j = get_dict_size(filename);    if (n_filename)        j += get_dict_size(n_filename);    if ((oovdic = cmd_ln_str("-oovdict")) != NULL)        j += get_dict_size(oovdic);    if ((personalDic = cmd_ln_str("-perdict")) != NULL) {        FILE *tmp;        /* personalDic exists */        if ((tmp = fopen(personalDic, "r")) != NULL)            j += get_dict_size(personalDic);        if (tmp)            fclose(tmp);    }    if ((max_new_oov = cmd_ln_int32("-maxnewoov")) > 0)        j += max_new_oov;    if ((startsym_file = cmd_ln_str("-startsymfn")) != NULL)        j += get_dict_size(startsym_file);    /* FIXME: <unk> is no longer used, is this still correct? */    j += 4;                     /* </s>, <s>, <unk> and <sil> */    if (dict->dict)        hash_table_free(dict->dict);    dict->dict = hash_table_new(j, HASH_CASE_NO);    /* Context table size hint: (#CI*#CI)/2 */    j = phoneCiCount();    j = ((j * j) >> 1) + 1;    mtpHT = hash_table_new(j, HASH_CASE_YES);    if (use_context) {        if (lcHT)            hash_table_free(lcHT);        lcHT = hash_table_new(j, HASH_CASE_YES);        if (rcHT)            hash_table_free(rcHT);        rcHT = hash_table_new(j, HASH_CASE_YES);        lcList.size_hint = j;        rcList.size_hint = j;    }    /* Load dictionaries */    dict_load(dict, filename, &word_id, use_context);    /* Add words with known pronunciations but which are OOVs wrt LM */    first_initial_oov = word_id;    if ((oovdic = cmd_ln_str("-oovdict")) != NULL)        dict_load(dict, oovdic, &word_id, use_context);    if ((personalDic = cmd_ln_str("-perdict")) != NULL) {        FILE *tmp;        /* personalDic exists */        if ((tmp = fopen(personalDic, "r")) != NULL)            dict_load(dict, personalDic, &word_id, use_context);        if (tmp != NULL)            fclose(tmp);    }    last_initial_oov = word_id - 1;    /* Placeholders (dummy pronunciations) for new words that can be added at runtime */    initial_dummy = first_dummy = word_id;    if ((max_new_oov = cmd_ln_int32("-maxnewoov")) > 0)        E_INFO("Allocating %d placeholders for new OOVs\n", max_new_oov);    for (i = 0; i < max_new_oov; i++) {        char tmpstr[100], pronstr[100];        /* Pick a temporary name that doesn't occur in the LM */        sprintf(tmpstr, "=PLCHLDR%d=", i);        /* new_dict_entry clobbers pronstr! so need this strcpy in the loop */        strcpy(pronstr, "SIL");        entry = _new_dict_entry(tmpstr, pronstr, TRUE);        if (!entry)            E_FATAL("Failed to add DUMMY(SIL) entry to dictionary\n");        _dict_list_add(dict, entry);        hash_table_enter(dict->dict, entry->word, (void *) word_id);        entry->wid = word_id;        entry->fwid = word_id;        word_id++;    }    last_dummy = word_id - 1;    /*     * Special case the start symbol and end symbol phrase markers.     * Special case the silence word 'SIL'.     */    {        void *val;        if (hash_table_lookup(dict->dict, cmd_ln_str("-lmendsym"), &val) != 0) {            /*             * Check if there is a special end silence phone.             */            if (NO_PHONE == phone_to_id("SILe", FALSE)) {                entry = _new_dict_entry(cmd_ln_str("-lmendsym"), "SIL", FALSE);                if (!entry)                    E_FATAL("Failed to add </s>(SIL) to dictionary\n");            }            else {                E_INFO("Using special end silence for %s\n",                       cmd_ln_str("-lmendsym"));                entry =                    _new_dict_entry(cmd_ln_str("-lmendsym"), "SILe", FALSE);            }            _dict_list_add(dict, entry);            hash_table_enter(dict->dict, entry->word, (void *) word_id);            entry->wid = word_id;            entry->fwid = word_id;            word_id++;        }        /* Mark the start of filler words */        dict->filler_start = word_id;        /* Add [multiple] start symbols to dictionary (LISTEN project) */        if ((startsym_file = cmd_ln_str("-startsymfn")) != NULL) {            FILE *ssfp;            char line[1000], startsym[1000];            char *startsym_phone;            E_INFO("Reading start-syms file %s\n", startsym_file);            startsym_phone =                ckd_salloc((phone_to_id("SILb", FALSE) == NO_PHONE) ? "SIL" : "SILb");            ssfp = myfopen(startsym_file, "r");            while (fgets(line, sizeof(line), ssfp) != NULL) {                if (sscanf(line, "%s", startsym) != 1)                    E_FATAL("File format error\n");                entry = _new_dict_entry(startsym, startsym_phone, FALSE);                if (!entry)                    E_FATAL("Failed to add %s to dictionary\n", startsym);                _dict_list_add(dict, entry);                hash_table_enter(dict->dict, entry->word, (void *) word_id);                entry->wid = word_id;                entry->fwid = word_id;                word_id++;            }            ckd_free(startsym_phone);        }        /* Add the standard start symbol (<s>) if not already in dict */        if (hash_table_lookup(dict->dict, cmd_ln_str("-lmstartsym"), &val) != 0) {            /*             * Check if there is a special begin silence phone.             */            if (NO_PHONE == phone_to_id("SILb", FALSE)) {                entry =                    _new_dict_entry(cmd_ln_str("-lmstartsym"), "SIL", FALSE);                if (!entry)                    E_FATAL("Failed to add <s>(SIL) to dictionary\n");            }            else {                E_INFO("Using special begin silence for %s\n",                       cmd_ln_str("-lmstartsym"));                entry =                    _new_dict_entry(cmd_ln_str("-lmstartsym"), "SILb", FALSE);                if (!entry)                    E_FATAL("Failed to add <s>(SILb) to dictionary\n");            }            _dict_list_add(dict, entry);            hash_table_enter(dict->dict, entry->word, (void *) word_id);            entry->wid = word_id;            entry->fwid = word_id;            word_id++;        }        /* Finally create a silence phone if it isn't there already. */        if (hash_table_lookup(dict->dict, "SIL", &val) != 0) {            entry = _new_dict_entry("SIL", "SIL", FALSE);            if (!entry)                E_FATAL("Failed to add <sil>(SIL) to dictionary\n");            _dict_list_add(dict, entry);            hash_table_enter(dict->dict, entry->word, (void *) word_id);            entry->wid = word_id;            entry->fwid = word_id;            word_id++;        }    }    if (n_filename)        dict_load(dict, n_filename, &word_id, FALSE /* use_context */);    E_INFO("LEFT CONTEXT TABLES\n");    buildEntryTable(&lcList, &lcFwdTable);    buildExitTable(&lcList, &lcBwdTable, &lcBwdPermTable, &lcBwdSizeTable);    E_INFO("RIGHT CONTEXT TABLES\n");    buildEntryTable(&rcList, &rcBwdTable);    buildExitTable(&rcList, &rcFwdTable, &rcFwdPermTable, &rcFwdSizeTable);    mtpList = hash_table_tolist(mtpHT, &i);    E_INFO("%5d unique triphones were mapped to ci phones\n", i);    hash_table_free(mtpHT);    mtpHT = NULL;    return (retval);}voiddict_free(dictT * dict){    int32 i;    int32 entry_count;    dict_entry_t *entry;    entry_count = dict->dict_entry_count;    for (i = 0; i < entry_count; i++) {        entry = dict_get_entry(dict, i);        free(entry->word);        free(entry->phone_ids);        free(entry->ci_phone_ids);

⌨️ 快捷键说明

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