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

📄 htklattice.cc

📁 这是一款很好用的工具包
💻 CC
📖 第 1 页 / 共 4 页
字号:
			nodeinfo.xscore3 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x4")) {
			nodeinfo.xscore4 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x5")) {
			nodeinfo.xscore5 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x6")) {
			nodeinfo.xscore6 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x7")) {
			nodeinfo.xscore7 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x8")) {
			nodeinfo.xscore8 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("x9")) {
			nodeinfo.xscore9 = getHTKscore(value, HTKlogbase, file);
		    } else if (keyis("p")) {
			nodeinfo.posterior = atof(value);
		    } else {
			file.position() << "unexpected node field name "
					<< key << endl;
			if (!useNullNodes) vocab.remove(HTKNodeDummy);
			return false;
		    }
		}

		if (nodeinfo.time != HTK_undef_float) {
		    // record node time, but no word-related info
		    LatticeNode *nullNode = findNode(nullNodeIndex);
		    assert(nullNode != 0);

		    HTKWordInfo *nullInfo = new HTKWordInfo;
		    assert(nullInfo != 0);
		    htkinfos[htkinfos.size()] = nullInfo;

		    nullNode->htkinfo = nullInfo;
		    nullInfo->time = nodeinfo.time;
		}

		continue;

	    /*
	     * Header fields
	     */
	    } else if (keyis("V") || keyis("VERSION")) {
		; 		// ignore
	    } else if ( keyis("U") || keyis("UTTERANCE")) {
		if (name) free((void *)name);

		// HACK: strip duration spec (which shouldn't be there)
		char *p = strstr(value, "(duration=");
		if (p != 0) *p = '\0';
		    
		name = strdup(value);
		assert(name != 0);
	    } else if (keyis("base")) {
		HTKlogbase = (float)atof(value);

		if (HTKwdpenalty[0] &&
		    (header == 0 || header->wdpenalty == HTK_undef_float))
		{
		    // recompute wdpenalty with new logbase
		    htkheader.wdpenalty =
				    getHTKscore(HTKwdpenalty, HTKlogbase, file);
		}
	    } else if (keyis("start")) {
		HTKinitial = atoi(value);
	    } else if (keyis("end")) {
		HTKfinal = atoi(value);
	    } else if (keyis("dir")) {
		HTKdirection = value[0];
	    } else if (keyis("tscale")) {
		htkheader.tscale = atof(value);
	    } else if (keyis("hmms")) {
		htkheader.hmms = strdup(value);
		assert(htkheader.hmms != 0);
	    } else if (keyis("ngname")) {
		htkheader.ngname = strdup(value);
		assert(htkheader.ngname != 0);
	    } else if (keyis("lmname")) {
		htkheader.lmname = strdup(value);
		assert(htkheader.lmname != 0);
	    } else if (keyis("vocab")) {
		htkheader.vocab = strdup(value);
		assert(htkheader.vocab != 0);
	    } else if (keyis("acscale")) {
		if (header == 0 || header->acscale == HTK_undef_float) {
		    htkheader.acscale = atof(value);
		}
	    } else if (keyis("ngscale")) {
		if (header == 0 || header->ngscale == HTK_undef_float) {
		    htkheader.ngscale = atof(value);
		}
	    } else if (keyis("lmscale")) {
		if (header == 0 || header->lmscale == HTK_undef_float) {
		    htkheader.lmscale = atof(value);
		}
	    } else if (keyis("prscale")) {
		if (header == 0 || header->prscale == HTK_undef_float) {
		    htkheader.prscale = atof(value);
		}
	    } else if (keyis("duscale")) {
		if (header == 0 || header->duscale == HTK_undef_float) {
		    htkheader.duscale = atof(value);
		}
	    } else if (keyis("wdpenalty")) {
		if (header == 0 || header->wdpenalty == HTK_undef_float) {
		    htkheader.wdpenalty = getHTKscore(value, HTKlogbase, file);
		    strncpy(HTKwdpenalty, value, sizeof(HTKwdpenalty)-1);
		}
	    } else if (keyis("x1scale")) {
		if (header == 0 || header->x1scale == HTK_undef_float) {
		    htkheader.x1scale = atof(value);
		}
	    } else if (keyis("x2scale")) {
		if (header == 0 || header->x2scale == HTK_undef_float) {
		    htkheader.x2scale = atof(value);
		}
	    } else if (keyis("x3scale")) {
		if (header == 0 || header->x3scale == HTK_undef_float) {
		    htkheader.x3scale = atof(value);
		}
	    } else if (keyis("x4scale")) {
		if (header == 0 || header->x4scale == HTK_undef_float) {
		    htkheader.x4scale = atof(value);
		}
	    } else if (keyis("x5scale")) {
		if (header == 0 || header->x5scale == HTK_undef_float) {
		    htkheader.x5scale = atof(value);
		}
	    } else if (keyis("x6scale")) {
		if (header == 0 || header->x6scale == HTK_undef_float) {
		    htkheader.x6scale = atof(value);
		}
	    } else if (keyis("x7scale")) {
		if (header == 0 || header->x7scale == HTK_undef_float) {
		    htkheader.x7scale = atof(value);
		}
	    } else if (keyis("x8scale")) {
		if (header == 0 || header->x8scale == HTK_undef_float) {
		    htkheader.x8scale = atof(value);
		}
	    } else if (keyis("x9scale")) {
		if (header == 0 || header->x9scale == HTK_undef_float) {
		    htkheader.x9scale = atof(value);
		}
	    } else if (keyis("amscale")) {
		if (header == 0 || header->amscale == HTK_undef_float) {
		    htkheader.amscale = atof(value);
		}
	    } else if (keyis("NODES") || keyis("N")) {
		HTKnumnodes = atoi(value);
	    } else if (keyis("LINKS") || keyis("L")) {
		HTKnumlinks = atoi(value);
	    } else {
		file.position() << "unknown field name " << key << endl;
		if (!useNullNodes) vocab.remove(HTKNodeDummy);
		return false;
	    }
#undef keyis
	}
    }

    if (HTKnumnodes == 0) {
	file.position() << "lattice has no nodes\n";
	if (!useNullNodes) vocab.remove(HTKNodeDummy);
	return false;
    }

    /*
     * Set up initial node
     */
    HTKWordInfo *initialinfo;
    LatticeNode *initialNode;

    if (HTKinitial != HTK_undef_uint) {
	initialinfo = &nodeInfoMap[HTKinitial];
	NodeIndex *initialPtr = nodeMap.find(HTKinitial);
	if (initialPtr) {
	    initial = *initialPtr;
	    initialNode = findNode(initial);
	} else {
	    file.position() << "undefined start node " << HTKinitial << endl;
	    if (!useNullNodes) vocab.remove(HTKNodeDummy);
	    return false;
	}
    } else {
	// search for start node: the one without incoming transitions
	LHashIter<NodeIndex, LatticeNode> nodeIter(nodes);
	NodeIndex nodeIndex;
	while (LatticeNode *node = nodeIter.next(nodeIndex)) {
	    if (node->inTransitions.numEntries() == 0) {
		initial = nodeIndex;
		initialNode = node;
		break;
	    }
	}

	// now find the HTK node info associated with first node
	LHashIter<unsigned, NodeIndex> nodeMapIter(nodeMap);
	unsigned htkNode;
	while (NodeIndex *pfsgNode = nodeMapIter.next(htkNode)) {
	    if (*pfsgNode == initial) {
		HTKinitial = htkNode;
		initialinfo = &nodeInfoMap[HTKinitial];
		break;
	    }
	}
    }
    initialNode->word = vocab.ssIndex();

    // attach HTK initial node info to lattice initial node
    if (initialinfo) {
	initialNode->htkinfo = new HTKWordInfo(*initialinfo);
	assert(initialNode->htkinfo != 0);
	htkinfos[htkinfos.size()] = initialNode->htkinfo;
    }

    /*
     * Set up final node
     */
    HTKWordInfo *finalinfo;
    LatticeNode *finalNode;

    if (HTKfinal != HTK_undef_uint) {
	finalinfo = &nodeInfoMap[HTKfinal];
	NodeIndex *finalPtr = nodeMap.find(HTKfinal);
	if (finalPtr) {
	    final = *finalPtr;
	    finalNode = findNode(final);
	} else {
	    file.position() << "undefined end node " << HTKfinal << endl;
	    if (!useNullNodes) vocab.remove(HTKNodeDummy);
	    return false;
	}
    } else {
	// search for end node: the one without outgoing transitions
	LHashIter<NodeIndex, LatticeNode> nodeIter(nodes);
	NodeIndex nodeIndex;
	while (LatticeNode *node = nodeIter.next(nodeIndex)) {
	    if (node->outTransitions.numEntries() == 0) {
		final = nodeIndex;
		finalNode = node;
		break;
	    }
	}

	// now find the HTK node info associated with final node
	LHashIter<unsigned, NodeIndex> nodeMapIter(nodeMap);
	unsigned htkNode;
	while (NodeIndex *pfsgNode = nodeMapIter.next(htkNode)) {
	    if (*pfsgNode == final) {
		HTKfinal = htkNode;
		finalinfo = &nodeInfoMap[HTKfinal];
		break;
	    }
	}
    }
    finalNode->word = vocab.seIndex();

    // attach HTK final node info to lattice final node
    if (finalinfo) {
	finalNode->htkinfo = new HTKWordInfo(*finalinfo);
	assert(finalNode->htkinfo != 0);
	htkinfos[htkinfos.size()] = finalNode->htkinfo;
    }

    // eliminate dummy nodes 
    if (!useNullNodes) {
	removeAllXNodes(HTKNodeDummy);
	vocab.remove(HTKNodeDummy);
    }

    return true;
}

/*
 * allowAsTrans()
 *  Determine if this node has the appropriate properties to be printed 
 *  as just an HTK transition.  The purpose is to allow a more compact printing.
 *  If an internal lattice node meets these characteristics then it need not 
 *  be printed as an HTK node, and it's transitions can also be saved from
 *  printing because the node itself will be printed as the transition.
 * 
 *  Check for these properties:
 *    - must have one outgoing transition
 *    - must have one incoming transition
 *    - nodes on each side must be HTK null nodes
 *    - don't allow as a transition if an adjacent node could also be allowed
 *      (this last case should allow for the collapsing of these two nodes,
 *	but it's not impl.)
 */
static Boolean
allowAsTrans(Lattice &lat, NodeIndex nodeIndex)
{
    LatticeNode *node = lat.findNode(nodeIndex);
    assert(node != 0);
  
    if (node->inTransitions.numEntries() == 1 &&
	node->outTransitions.numEntries() == 1)
    {
	TRANSITER_T<NodeIndex,LatticeTransition>
	    outTransIter(node->outTransitions);
	NodeIndex next;
	while (outTransIter.next(next)) {
	    LatticeNode *nextNode = lat.findNode(next); 
	    assert(nextNode != 0);
	    // check if next node is a NULL (the final node also acts as one)
	    if (nextNode->word == Vocab_None || next == lat.getFinal()) {
		TRANSITER_T<NodeIndex,LatticeTransition> 
		    inTransIter(node->inTransitions);
		NodeIndex prev;
		while (inTransIter.next(prev)) {
		    LatticeNode *prevNode = lat.findNode(prev); 
		    assert(prevNode != 0);

		    // check if prev node is a NULL
		    // (the inital node also acts as one)
		    if (prevNode->word == Vocab_None ||
			prev == lat.getInitial())
		    {
			// check if next node would be allowed as a transition
			if (allowAsTrans(lat, next)) {
			    // if we have a string of two nodes that could be
			    // transitions, that should be redundant and allow
			    // them to be combined, for now we'll just treat
			    // it as a case that returns false because two
			    // adjacent transitions is a problem (a node
			    // between them is required) so the first node
			    // will not be allowed as a transition
			    return false;
			} else {
			    return true;
			}
		    }
		}
	    }
	}
    }
    return false;
}

static double
scaleHTKScore(double score, double logscale)
{
    if (logscale == 0.0) {
	return LogPtoProb(score);
    } else {
	return score * logscale;
    }
}

static void
writeScoreInfo(File &file, HTKWordInfo &htkinfo, HTKScoreMapping scoreMapping,
								double logscale)
{
    if (scoreMapping != mapHTKacoustic &&
	  htkinfo.acoustic != HTK_undef_float)
    {
	fprintf(file, "\ta=%lg", scaleHTKScore(htkinfo.acoustic, logscale));
    }
    if (htkinfo.pron != HTK_undef_float)
    {
	fprintf(file, "\tr=%lg", scaleHTKScore(htkinfo.pron, logscale));
    }
    if (htkinfo.duration != HTK_undef_float)
    {
	fprintf(file, "\tds=%lg", scaleHTKScore(htkinfo.duration, logscale));
    }
    if (htkinfo.xscore1 != HTK_undef_float)
    {
	fprintf(file, "\tx1=%lg", scaleHTKScore(htkinfo.xscore1, logscale));
    }
    if (htkinfo.xscore2 != HTK_undef_float)
    {
	fprintf(file, "\tx2=%lg", scaleHTKScore(htkinfo.xscore2, logscale));
    }
    if (htkinfo.xscore3 != HTK_undef_float)
    {
	fprintf(file, "\tx3=%lg", scaleHTKScore(htkinfo.xscore3, logscale));
    }
    if (htkinfo.xscore4 != HTK_undef_float)
    {
	fprintf(file, "\tx4=%lg", scaleHTKScore(htkinfo.xscore4, logscale));
    }
    if (htkinfo.xscore5 != HTK_undef_float)
    {
	fprintf(file, "\tx5=%lg", scaleHTKScore(htkinfo.xscore5, logscale));
    }
    if (htkinfo.xscore6 != HTK_undef_float)
    {
	fprintf(file, "\tx6=%lg", scaleHTKScore(htkinfo.xscore6, logscale));
    }
    if (htkinfo.xscore7 != HTK_undef_float)
    {
	fprintf(file, "\tx7=%lg", scaleHTKScore(htkinfo.xscore7, logscale));
    }
    if (htkinfo.xscore8 != HTK_undef_float)
    {
	fprintf(file, "\tx8=%lg", scaleHTKScore(htkinfo.xscore8, logscale));
    }
    if (htkinfo.xscore9 != HTK_undef_float)
    {
	fprintf(file, "\tx9=%lg", scaleHTKScore(htkinfo.xscore9, logscale));
    }
}

static void
writeWordInfo(File &file, HTKWordInfo &htkinfo)
{
    if (htkinfo.var != HTK_undef_uint)
    {
	fprintf(file, "\tv=%u", htkinfo.var);
    }
    if (htkinfo.div != 0)
    {
	fprintf(file, "\td=%s", htkinfo.div);
    }
    if (htkinfo.states != 0)
    {
	fprintf(file, "\ts=%s", htkinfo.states);
    }
}

/*
 * Output lattice in HTK format
 *	Algorithm:
 *	- each lattice node becomes an HTK node
 *        (unless it has only one incoming and one outgoing transition,
 *	  both to HTK null nodes)
 *	- each lattice transitions becomes an HTK link.
 *        (unless it exists on a node which has been flagged to print as a
 *	  transition, then the links are ignored)
 *	- word information is added to the HTK nodes.
 *        (all words and scores must be printed on the HTK transitions,
 *	  not on the words)
 *	- link information attached to each node is added to the HTK link
 *	  leading into the node.
 *	- lattice transition weights are mapped to one of the
 *	  HTK score fields as indicated by the second argument.
 */

⌨️ 快捷键说明

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